Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable csv2shp build with MSVC #62

Merged
merged 1 commit into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 15 additions & 24 deletions cmake/contrib.cmake
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
if(BUILD_SHAPELIB_CONTRIB)
if(NOT MSVC)
add_executable(csv2shp ${PROJECT_SOURCE_DIR}/contrib/csv2shp.c)
target_link_libraries(csv2shp shp)
set_target_properties(csv2shp PROPERTIES FOLDER "contrib")
add_executable(csv2shp ${PROJECT_SOURCE_DIR}/contrib/csv2shp.c)
target_link_libraries(csv2shp shp)
set_target_properties(csv2shp PROPERTIES FOLDER "contrib")

install(
TARGETS csv2shp
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()

add_executable(dbfcat ${PROJECT_SOURCE_DIR}/contrib/dbfcat.c)
target_link_libraries(dbfcat shp)
set_target_properties(dbfcat PROPERTIES FOLDER "contrib")
Expand Down Expand Up @@ -59,17 +49,18 @@ if(BUILD_SHAPELIB_CONTRIB)

install(
TARGETS
dbfcat
dbfinfo
shpcat
shpdxf
shpfix
shpsort
Shape_PointInPoly
shpcentrd
shpdata
shpinfo
shpwkb
csv2shp
dbfcat
dbfinfo
shpcat
shpdxf
shpfix
shpsort
Shape_PointInPoly
shpcentrd
shpdata
shpinfo
shpwkb
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
Expand Down
117 changes: 65 additions & 52 deletions contrib/csv2shp.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,24 @@ Email: <http://springsrescuemission.org/email.php?recipient=webmaster>

*/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "shapefil.h"
#include "regex.h"

#define MAX_COLUMNS 30

#if defined(_MSC_VER)
#define STRCASECMP(a, b) (_stricmp(a, b))
#elif defined(WIN32) || defined(_WIN32)
#define STRCASECMP(a, b) (stricmp(a, b))
#else
#include <strings.h>
#define STRCASECMP(a, b) (strcasecmp(a, b))
#endif

typedef struct column_t
{
DBFFieldType eType;
Expand All @@ -81,7 +90,7 @@ int strnchr(const char *s, char c)
{
int n = 0;

for (int x = 0; x < strlen(s); x++)
for (size_t x = 0; x < strlen(s); x++)
{
if (c == s[x])
{
Expand Down Expand Up @@ -127,41 +136,65 @@ char *delimited_column(char *s, char delim, int n)
return szreturn;
}

/* Determines the most specific column type.
The most specific types from most to least are integer, float, string. */
DBFFieldType str_to_fieldtype(const char *s)
/* returns the number of decimals in a real number given as a string s */
int str_to_ndecimals(const char *s)
{
regex_t regex_i;
if (0 != regcomp(&regex_i, "^[0-9]+$", REG_NOSUB | REG_EXTENDED))
if (s == NULL)
{
fprintf(stderr, "integer regex complication failed\n");
exit(EXIT_FAILURE);
return -1;
}

if (0 == regexec(&regex_i, s, 0, NULL, 0))
/* Check for float: ^-?[0-9]+\.[0-9]+$ */
if (!isdigit(s[0]) && s[0] != '-')
{
regfree(&regex_i);
return FTInteger;
return -1;
}

regfree(&regex_i);
size_t len = strlen(s);
if (!isdigit(s[len - 1]))
{
return -1;
}

regex_t regex_d;
if (0 != regcomp(&regex_d, "^-?[0-9]+\\.[0-9]+$", REG_NOSUB | REG_EXTENDED))
const char* decimalPoint = strchr(s, '.');
if ((decimalPoint == NULL) || (strchr(decimalPoint + 1, '.') != NULL))
{
fprintf(stderr, "integer regex complication failed\n");
exit(EXIT_FAILURE);
return -1;
}

if (0 == regexec(&regex_d, s, 0, NULL, 0))
for (size_t x = 1; x < len - 1; x++)
{
regfree(&regex_d);
return FTDouble;
if (!isdigit(s[x]) && s[x] != '.')
{
return -1;
}
}

regfree(&regex_d);
return (int)strlen(decimalPoint + 1);
}

/* Determines the most specific column type.
The most specific types from most to least are integer, float, string. */
DBFFieldType str_to_fieldtype(const char *s)
{
size_t len = strlen(s);

return FTString;
/* Check for integer: ^[0-9]+$ */
int isInteger = 1;
for (size_t x = 0; x < len; x++)
{
if (!isdigit(s[x]))
{
isInteger = 0;
break;
}
}
if (isInteger)
{
return FTInteger;
}

return str_to_ndecimals(s) > 0 ? FTDouble : FTString;
}

/* returns the field width */
Expand All @@ -172,39 +205,14 @@ int str_to_nwidth(const char *s, DBFFieldType eType)
case FTString:
case FTInteger:
case FTDouble:
return strlen(s);
return (int)strlen(s);

default:
fprintf(stderr, "str_to_nwidth: unexpected type\n");
exit(EXIT_FAILURE);
}
}

/* returns the number of decimals in a real number given as a string s */
int str_to_ndecimals(const char *s)
{
regex_t regex_d;
if (0 != regcomp(&regex_d, "^-?[0-9]+\\.([0-9]+)$", REG_EXTENDED))
{
fprintf(stderr, "integer regex complication failed\n");
exit(EXIT_FAILURE);
}

regmatch_t pmatch[2];
if (0 != regexec(&regex_d, s, 2, &pmatch[0], 0))
{
return -1;
}

char szbuffer[4096];
strncpy(szbuffer, &s[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
szbuffer[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';

regfree(&regex_d);

return strlen(szbuffer);
}

/* returns true if f1 is more general than f2, otherwise false */
int more_general_field_type(DBFFieldType t1, DBFFieldType t2)
{
Expand Down Expand Up @@ -329,13 +337,13 @@ int main(int argc, char **argv)
for (int x = 0; x <= n_columns; x++)
{
if (0 ==
strcasecmp("Longitude", delimited_column(sbuffer, delimiter, x)))
STRCASECMP("Longitude", delimited_column(sbuffer, delimiter, x)))
{
n_longitude = x;
}

else
if (0 ==
strcasecmp("Latitude", delimited_column(sbuffer, delimiter, x)))
STRCASECMP("Latitude", delimited_column(sbuffer, delimiter, x)))
{
n_latitude = x;
}
Expand All @@ -354,7 +362,7 @@ int main(int argc, char **argv)

/* determine best fit for each column */

printf("Anaylzing column types...\n");
printf("Analyzing column types...\n");

#ifdef DEBUG
printf("debug: string type = %i\n", FTString);
Expand All @@ -374,6 +382,7 @@ int main(int argc, char **argv)

fseek(csv_f, 0, SEEK_SET);
fgets(sbuffer, 4000, csv_f);
strip_crlf(sbuffer);

while (!feof(csv_f))
{
Expand All @@ -389,6 +398,7 @@ int main(int argc, char **argv)
}
continue;
}
strip_crlf(sbuffer);

char szfield[4096];
strcpy(szfield, delimited_column(sbuffer, delimiter, x));
Expand All @@ -400,6 +410,7 @@ int main(int argc, char **argv)
columns[x].nDecimals = 0;
fseek(csv_f, 0, SEEK_SET);
fgets(sbuffer, 4000, csv_f);
strip_crlf(sbuffer);
continue;
}
if (columns[x].nWidth < str_to_nwidth(szfield, columns[x].eType))
Expand Down Expand Up @@ -450,6 +461,7 @@ int main(int argc, char **argv)

fseek(csv_f, 0, SEEK_SET);
fgets(sbuffer, 4000, csv_f); /* skip header */
strip_crlf(sbuffer);

n_columns = strnchr(sbuffer, delimiter);
n_line = 1;
Expand All @@ -458,6 +470,7 @@ int main(int argc, char **argv)
{
n_line++;
fgets(sbuffer, 4000, csv_f);
strip_crlf(sbuffer);

/* write to shape file */
double x_pt = atof(delimited_column(sbuffer, delimiter, n_longitude));
Expand Down