Skip to content

Commit

Permalink
Merge pull request #62 from thbeu/build-csv2shp-msvc
Browse files Browse the repository at this point in the history
Enable csv2shp build with MSVC
  • Loading branch information
rouault authored Nov 3, 2023
2 parents 55de459 + 23044a3 commit 7a0e253
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 76 deletions.
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

0 comments on commit 7a0e253

Please sign in to comment.