Index: Makefile-static-MinGW ================================================================== --- Makefile-static-MinGW +++ Makefile-static-MinGW @@ -9,21 +9,21 @@ ./static_bin/spatialite_network.exe ./static_bin/shp_doctor.exe \ ./static_bin/exif_loader.exe ./static_bin/spatialite_osm_net.exe \ ./static_bin/spatialite_osm_map.exe ./static_bin/spatialite_gml.exe \ ./static_bin/spatialite_osm_raw.exe ./static_bin/spatialite_osm_filter.exe \ ./static_bin/spatialite_convert.exe ./static_bin/spatialite_dxf.exe \ - ./static_bin/spatialite_osm_overpass.exe \ + ./static_bin/spatialite_osm_overpass.exe ./static_bin/shp_sanitize.exe \ ./static_bin/spatialite_xml_collapse.exe \ ./static_bin/spatialite_xml_validator.exe \ ./static_bin/spatialite_xml_load.exe \ ./static_bin/spatialite_xml_print.exe ./static_bin/spatialite.exe: shell.o $(GG) shell.o -o ./static_bin/spatialite.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -36,11 +36,11 @@ ./static_bin/spatialite_tool.exe: spatialite_tool.o $(GG) spatialite_tool.o -o \ ./static_bin/spatialite_tool.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -53,11 +53,11 @@ ./static_bin/spatialite_convert.exe: spatialite_convert.o $(GG) spatialite_convert.o -o \ ./static_bin/spatialite_convert.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -70,11 +70,11 @@ ./static_bin/spatialite_dxf.exe: spatialite_dxf.o $(GG) spatialite_dxf.o -o \ ./static_bin/spatialite_dxf.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -86,11 +86,11 @@ ./static_bin/spatialite_network.exe: spatialite_network.o $(GG) spatialite_network.o -o ./static_bin/spatialite_network.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -102,11 +102,11 @@ ./static_bin/shp_doctor.exe: shp_doctor.o $(GG) shp_doctor.o -o ./static_bin/shp_doctor.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -114,15 +114,31 @@ /usr/local/lib/libz.a \ /usr/local/lib/libiconv.a \ -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc strip --strip-all ./static_bin/shp_doctor.exe +./static_bin/shp_sanitize.exe: shp_sanitize.o + $(GG) shp_sanitize.o -o ./static_bin/shp_sanitize.exe \ + /usr/local/lib/libspatialite.a \ + /usr/local/lib/libsqlite3.a \ + /usr/local/lib/librttopo.a \ + /usr/local/lib/libxml2.a \ + /usr/local/lib/liblzma.a \ + /usr/local/lib/libproj.a \ + /usr/local/lib/libgeos_c.a \ + /usr/local/lib/libgeos.a \ + /usr/local/lib/libfreexl.a \ + /usr/local/lib/libz.a \ + /usr/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/shp_sanitize.exe + ./static_bin/exif_loader.exe: exif_loader.o $(GG) exif_loader.o -o ./static_bin/exif_loader.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -134,11 +150,11 @@ ./static_bin/spatialite_osm_net.exe: spatialite_osm_net.o $(GG) spatialite_osm_net.o -o ./static_bin/spatialite_osm_net.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -152,11 +168,11 @@ ./static_bin/spatialite_osm_map.exe: spatialite_osm_map.o $(GG) spatialite_osm_map.o -o ./static_bin/spatialite_osm_map.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -170,11 +186,11 @@ ./static_bin/spatialite_gml.exe: spatialite_gml.o $(GG) spatialite_gml.o -o ./static_bin/spatialite_gml.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -187,11 +203,11 @@ ./static_bin/spatialite_osm_raw.exe: spatialite_osm_raw.o $(GG) spatialite_osm_raw.o -o ./static_bin/spatialite_osm_raw.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -205,11 +221,11 @@ ./static_bin/spatialite_osm_filter.exe: spatialite_osm_filter.o $(GG) spatialite_osm_filter.o -o ./static_bin/spatialite_osm_filter.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -221,11 +237,11 @@ ./static_bin/spatialite_osm_overpass.exe: spatialite_osm_overpass.o $(GG) spatialite_osm_overpass.o -o ./static_bin/spatialite_osm_overpass.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -237,11 +253,11 @@ ./static_bin/spatialite_xml_collapse.exe: spatialite_xml_collapse.o $(GG) spatialite_xml_collapse.o -o ./static_bin/spatialite_xml_collapse.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -262,11 +278,11 @@ ./static_bin/spatialite_xml_load.exe: spatialite_xml_load.o $(GG) spatialite_xml_load.o -o ./static_bin/spatialite_xml_load.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -279,11 +295,11 @@ ./static_bin/spatialite_xml_print.exe: spatialite_xml_print.o $(GG) spatialite_xml_print.o -o ./static_bin/spatialite_xml_print.exe \ /usr/local/lib/libspatialite.a \ /usr/local/lib/libsqlite3.a \ - /usr/local/lib/liblwgeom.a \ + /usr/local/lib/librttopo.a \ /usr/local/lib/libxml2.a \ /usr/local/lib/liblzma.a \ /usr/local/lib/libproj.a \ /usr/local/lib/libgeos_c.a \ /usr/local/lib/libgeos.a \ @@ -302,10 +318,13 @@ spatialite_network.o: $(CC) $(CFLAGS) spatialite_network.c -c shp_doctor.o: $(CC) $(CFLAGS) shp_doctor.c -c + +shp_sanitize.o: + $(CC) $(CFLAGS) shp_sanitize.c -c exif_loader.o: $(CC) $(CFLAGS) exif_loader.c -c spatialite_osm_net.o: ADDED Makefile-static-mingw32 Index: Makefile-static-mingw32 ================================================================== --- Makefile-static-mingw32 +++ Makefile-static-mingw32 @@ -0,0 +1,369 @@ +# SandroFurieri (c) 2009 +# Makefile Spatialite statically linked CLI-tools [Win MSYS/MinGW] + +CFLAGS = -Wall -Wextra -Wunused -pedantic -I/mingw32/local/include +GG = g++ -static +CC = gcc -static + +all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \ + ./static_bin/spatialite_network.exe ./static_bin/shp_doctor.exe \ + ./static_bin/exif_loader.exe ./static_bin/spatialite_osm_net.exe \ + ./static_bin/spatialite_osm_map.exe ./static_bin/spatialite_gml.exe \ + ./static_bin/spatialite_osm_raw.exe ./static_bin/spatialite_osm_filter.exe \ + ./static_bin/spatialite_convert.exe ./static_bin/spatialite_dxf.exe \ + ./static_bin/spatialite_osm_overpass.exe ./static_bin/shp_sanitize.exe \ + ./static_bin/spatialite_xml_collapse.exe \ + ./static_bin/spatialite_xml_validator.exe \ + ./static_bin/spatialite_xml_load.exe \ + ./static_bin/spatialite_xml2utf8.exe \ + ./static_bin/spatialite_xml_print.exe + +./static_bin/spatialite.exe: shell.o + $(GG) shell.o -o ./static_bin/spatialite.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite.exe + +./static_bin/spatialite_tool.exe: spatialite_tool.o + $(GG) spatialite_tool.o -o \ + ./static_bin/spatialite_tool.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_tool.exe + +./static_bin/spatialite_convert.exe: spatialite_convert.o + $(GG) spatialite_convert.o -o \ + ./static_bin/spatialite_convert.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_convert.exe + +./static_bin/spatialite_dxf.exe: spatialite_dxf.o + $(GG) spatialite_dxf.o -o \ + ./static_bin/spatialite_dxf.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_dxf.exe + +./static_bin/spatialite_network.exe: spatialite_network.o + $(GG) spatialite_network.o -o ./static_bin/spatialite_network.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_network.exe + +./static_bin/shp_doctor.exe: shp_doctor.o + $(GG) shp_doctor.o -o ./static_bin/shp_doctor.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/shp_doctor.exe + +./static_bin/shp_sanitize.exe: shp_sanitize.o + $(GG) shp_sanitize.o -o ./static_bin/shp_sanitize.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/shp_sanitize.exe + +./static_bin/exif_loader.exe: exif_loader.o + $(GG) exif_loader.o -o ./static_bin/exif_loader.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/exif_loader.exe + +./static_bin/spatialite_osm_net.exe: spatialite_osm_net.o + $(GG) spatialite_osm_net.o -o ./static_bin/spatialite_osm_net.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libreadosm.a \ + /mingw32/local/lib/libiconv.a \ + /mingw32/local/lib/libexpat.a \ + /mingw32/local/lib/libz.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_net.exe + +./static_bin/spatialite_osm_map.exe: spatialite_osm_map.o + $(GG) spatialite_osm_map.o -o ./static_bin/spatialite_osm_map.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libiconv.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libreadosm.a \ + /mingw32/local/lib/libexpat.a \ + /mingw32/local/lib/libz.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_map.exe + +./static_bin/spatialite_gml.exe: spatialite_gml.o + $(GG) spatialite_gml.o -o ./static_bin/spatialite_gml.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + /mingw32/local/lib/libexpat.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_gml.exe + +./static_bin/spatialite_osm_raw.exe: spatialite_osm_raw.o + $(GG) spatialite_osm_raw.o -o ./static_bin/spatialite_osm_raw.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libreadosm.a \ + /mingw32/local/lib/libiconv.a \ + /mingw32/local/lib/libexpat.a \ + /mingw32/local/lib/libz.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_raw.exe + +./static_bin/spatialite_osm_filter.exe: spatialite_osm_filter.o + $(GG) spatialite_osm_filter.o -o ./static_bin/spatialite_osm_filter.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_filter.exe + +./static_bin/spatialite_osm_overpass.exe: spatialite_osm_overpass.o + $(GG) spatialite_osm_overpass.o -o ./static_bin/spatialite_osm_overpass.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_overpass.exe + +./static_bin/spatialite_xml_collapse.exe: spatialite_xml_collapse.o + $(GG) spatialite_xml_collapse.o -o ./static_bin/spatialite_xml_collapse.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_collapse.exe + +./static_bin/spatialite_xml_validator.exe: spatialite_xml_validator.o + $(CC) spatialite_xml_validator.o -o ./static_bin/spatialite_xml_validator.exe \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lws2_32 -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_validator.exe + +./static_bin/spatialite_xml_load.exe: spatialite_xml_load.o + $(GG) spatialite_xml_load.o -o ./static_bin/spatialite_xml_load.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libexpat.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_load.exe + +./static_bin/spatialite_xml2utf8.exe: spatialite_xml2utf8.o + $(CC) spatialite_xml2utf8.o -o ./static_bin/spatialite_xml2utf8.exe \ + /mingw32/local/lib/libiconv.a \ + -static-libgcc + strip --strip-all ./static_bin/spatialite_xml2utf8.exe + +./static_bin/spatialite_xml_print.exe: spatialite_xml_print.o + $(GG) spatialite_xml_print.o -o ./static_bin/spatialite_xml_print.exe \ + /mingw32/local/lib/libspatialite.a \ + /mingw32/local/lib/libsqlite3.a \ + /mingw32/local/lib/librttopo.a \ + /mingw32/local/lib/libxml2.a \ + /mingw32/local/lib/liblzma.a \ + /mingw32/local/lib/libproj.a \ + /mingw32/local/lib/libgeos_c.a \ + /mingw32/local/lib/libgeos.a \ + /mingw32/local/lib/libfreexl.a \ + /mingw32/local/lib/libz.a \ + /mingw32/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_print.exe + +shell.o: + $(CC) $(CFLAGS) shell.c -c + +spatialite_tool.o: + $(CC) $(CFLAGS) spatialite_tool.c -c + +spatialite_network.o: + $(CC) $(CFLAGS) spatialite_network.c -c + +shp_doctor.o: + $(CC) $(CFLAGS) shp_doctor.c -c + +shp_sanitize.o: + $(CC) $(CFLAGS) shp_sanitize.c -c + +exif_loader.o: + $(CC) $(CFLAGS) exif_loader.c -c + +spatialite_osm_net.o: + $(CC) $(CFLAGS) spatialite_osm_net.c -c + +spatialite_osm_map.o: + $(CC) $(CFLAGS) spatialite_osm_map.c -c + +spatialite_gml.o: + $(CC) $(CFLAGS) spatialite_gml.c -c + +spatialite_osm_raw.o: + $(CC) $(CFLAGS) spatialite_osm_raw.c -c + +spatialite_osm_filter.o: + $(CC) $(CFLAGS) spatialite_osm_filter.c -c + +spatialite_osm_overpass.o: + $(CC) $(CFLAGS) spatialite_osm_overpass.c -c + +spatialite_xml_collapse.o: + $(CC) $(CFLAGS) spatialite_xml_collapse.c -c + +spatialite_xml_validator.o: + $(CC) $(CFLAGS) spatialite_xml_validator.c -c + +spatialite_xml_load.o: + $(CC) $(CFLAGS) spatialite_xml_load.c -c + +spatialite_xml2utf8.o: + $(CC) $(CFLAGS) spatialite_xml2utf8.c -c + + +spatialite_xml_print.o: + $(CC) $(CFLAGS) spatialite_xml_print.c -c ADDED Makefile-static-mingw64 Index: Makefile-static-mingw64 ================================================================== --- Makefile-static-mingw64 +++ Makefile-static-mingw64 @@ -0,0 +1,368 @@ +# SandroFurieri (c) 2009 +# Makefile Spatialite statically linked CLI-tools [Win MSYS/MinGW] + +CFLAGS = -Wall -Wextra -Wunused -pedantic -I/mingw64/local/include +GG = g++ -static +CC = gcc -static + +all: ./static_bin/spatialite.exe ./static_bin/spatialite_tool.exe \ + ./static_bin/spatialite_network.exe ./static_bin/shp_doctor.exe \ + ./static_bin/exif_loader.exe ./static_bin/spatialite_osm_net.exe \ + ./static_bin/spatialite_osm_map.exe ./static_bin/spatialite_gml.exe \ + ./static_bin/spatialite_osm_raw.exe ./static_bin/spatialite_osm_filter.exe \ + ./static_bin/spatialite_convert.exe ./static_bin/spatialite_dxf.exe \ + ./static_bin/spatialite_osm_overpass.exe ./static_bin/shp_sanitize.exe \ + ./static_bin/spatialite_xml_collapse.exe \ + ./static_bin/spatialite_xml_validator.exe \ + ./static_bin/spatialite_xml_load.exe \ + ./static_bin/spatialite_xml2utf8.exe \ + ./static_bin/spatialite_xml_print.exe + +./static_bin/spatialite.exe: shell.o + $(GG) shell.o -o ./static_bin/spatialite.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite.exe + +./static_bin/spatialite_tool.exe: spatialite_tool.o + $(GG) spatialite_tool.o -o \ + ./static_bin/spatialite_tool.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_tool.exe + +./static_bin/spatialite_convert.exe: spatialite_convert.o + $(GG) spatialite_convert.o -o \ + ./static_bin/spatialite_convert.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_convert.exe + +./static_bin/spatialite_dxf.exe: spatialite_dxf.o + $(GG) spatialite_dxf.o -o \ + ./static_bin/spatialite_dxf.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_dxf.exe + +./static_bin/spatialite_network.exe: spatialite_network.o + $(GG) spatialite_network.o -o ./static_bin/spatialite_network.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_network.exe + +./static_bin/shp_doctor.exe: shp_doctor.o + $(GG) shp_doctor.o -o ./static_bin/shp_doctor.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/shp_doctor.exe + +./static_bin/shp_sanitize.exe: shp_sanitize.o + $(GG) shp_sanitize.o -o ./static_bin/shp_sanitize.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/shp_sanitize.exe + +./static_bin/exif_loader.exe: exif_loader.o + $(GG) exif_loader.o -o ./static_bin/exif_loader.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/exif_loader.exe + +./static_bin/spatialite_osm_net.exe: spatialite_osm_net.o + $(GG) spatialite_osm_net.o -o ./static_bin/spatialite_osm_net.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libreadosm.a \ + /mingw64/local/lib/libiconv.a \ + /mingw64/local/lib/libexpat.a \ + /mingw64/local/lib/libz.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_net.exe + +./static_bin/spatialite_osm_map.exe: spatialite_osm_map.o + $(GG) spatialite_osm_map.o -o ./static_bin/spatialite_osm_map.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libiconv.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libreadosm.a \ + /mingw64/local/lib/libexpat.a \ + /mingw64/local/lib/libz.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_map.exe + +./static_bin/spatialite_gml.exe: spatialite_gml.o + $(GG) spatialite_gml.o -o ./static_bin/spatialite_gml.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + /mingw64/local/lib/libexpat.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_gml.exe + +./static_bin/spatialite_osm_raw.exe: spatialite_osm_raw.o + $(GG) spatialite_osm_raw.o -o ./static_bin/spatialite_osm_raw.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libreadosm.a \ + /mingw64/local/lib/libiconv.a \ + /mingw64/local/lib/libexpat.a \ + /mingw64/local/lib/libz.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_raw.exe + +./static_bin/spatialite_osm_filter.exe: spatialite_osm_filter.o + $(GG) spatialite_osm_filter.o -o ./static_bin/spatialite_osm_filter.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_filter.exe + +./static_bin/spatialite_osm_overpass.exe: spatialite_osm_overpass.o + $(GG) spatialite_osm_overpass.o -o ./static_bin/spatialite_osm_overpass.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_osm_overpass.exe + +./static_bin/spatialite_xml_collapse.exe: spatialite_xml_collapse.o + $(GG) spatialite_xml_collapse.o -o ./static_bin/spatialite_xml_collapse.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_collapse.exe + +./static_bin/spatialite_xml_validator.exe: spatialite_xml_validator.o + $(CC) spatialite_xml_validator.o -o ./static_bin/spatialite_xml_validator.exe \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lws2_32 -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_validator.exe + +./static_bin/spatialite_xml_load.exe: spatialite_xml_load.o + $(GG) spatialite_xml_load.o -o ./static_bin/spatialite_xml_load.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libexpat.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_load.exe + +./static_bin/spatialite_xml2utf8.exe: spatialite_xml2utf8.o + $(CC) spatialite_xml2utf8.o -o ./static_bin/spatialite_xml2utf8.exe \ + /mingw64/local/lib/libiconv.a \ + -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_load.exe + +./static_bin/spatialite_xml_print.exe: spatialite_xml_print.o + $(GG) spatialite_xml_print.o -o ./static_bin/spatialite_xml_print.exe \ + /mingw64/local/lib/libspatialite.a \ + /mingw64/local/lib/libsqlite3.a \ + /mingw64/local/lib/librttopo.a \ + /mingw64/local/lib/libxml2.a \ + /mingw64/local/lib/liblzma.a \ + /mingw64/local/lib/libproj.a \ + /mingw64/local/lib/libgeos_c.a \ + /mingw64/local/lib/libgeos.a \ + /mingw64/local/lib/libfreexl.a \ + /mingw64/local/lib/libz.a \ + /mingw64/local/lib/libiconv.a \ + -lm -lmsimg32 -lws2_32 -static-libstdc++ -static-libgcc + strip --strip-all ./static_bin/spatialite_xml_print.exe + +shell.o: + $(CC) $(CFLAGS) shell.c -c + +spatialite_tool.o: + $(CC) $(CFLAGS) spatialite_tool.c -c + +spatialite_network.o: + $(CC) $(CFLAGS) spatialite_network.c -c + +shp_doctor.o: + $(CC) $(CFLAGS) shp_doctor.c -c + +shp_sanitize.o: + $(CC) $(CFLAGS) shp_sanitize.c -c + +exif_loader.o: + $(CC) $(CFLAGS) exif_loader.c -c + +spatialite_osm_net.o: + $(CC) $(CFLAGS) spatialite_osm_net.c -c + +spatialite_osm_map.o: + $(CC) $(CFLAGS) spatialite_osm_map.c -c + +spatialite_gml.o: + $(CC) $(CFLAGS) spatialite_gml.c -c + +spatialite_osm_raw.o: + $(CC) $(CFLAGS) spatialite_osm_raw.c -c + +spatialite_osm_filter.o: + $(CC) $(CFLAGS) spatialite_osm_filter.c -c + +spatialite_osm_overpass.o: + $(CC) $(CFLAGS) spatialite_osm_overpass.c -c + +spatialite_xml_collapse.o: + $(CC) $(CFLAGS) spatialite_xml_collapse.c -c + +spatialite_xml_validator.o: + $(CC) $(CFLAGS) spatialite_xml_validator.c -c + +spatialite_xml_load.o: + $(CC) $(CFLAGS) spatialite_xml_load.c -c + +spatialite_xml2utf8.o: + $(CC) $(CFLAGS) spatialite_xml2utf8.c -c + +spatialite_xml_print.o: + $(CC) $(CFLAGS) spatialite_xml_print.c -c Index: Makefile.am ================================================================== --- Makefile.am +++ Makefile.am @@ -2,26 +2,28 @@ if NO_READOSM bin_PROGRAMS = spatialite \ spatialite_tool \ spatialite_network \ - shp_doctor \ + shp_doctor shp_sanitize \ exif_loader \ spatialite_osm_filter \ spatialite_gml \ spatialite_convert \ spatialite_dxf \ spatialite_xml_validator \ spatialite_xml_load \ + spatialite_xml2utf8 \ spatialite_xml_collapse \ spatialite_xml_print \ - spatialite_osm_overpass + spatialite_osm_overpass \ + spatialite_dem else bin_PROGRAMS = spatialite \ spatialite_tool \ spatialite_network \ - shp_doctor \ + shp_doctor shp_sanitize \ exif_loader \ spatialite_osm_net \ spatialite_osm_map \ spatialite_osm_raw \ spatialite_osm_filter \ @@ -28,25 +30,29 @@ spatialite_gml \ spatialite_convert \ spatialite_dxf \ spatialite_xml_validator \ spatialite_xml_load \ + spatialite_xml2utf8 \ spatialite_xml_collapse \ spatialite_xml_print \ - spatialite_osm_overpass + spatialite_osm_overpass \ + spatialite_dem endif -AM_CPPFLAGS = @CFLAGS@ @LIBXML2_CFLAGS@ +AM_CPPFLAGS = @CFLAGS@ @CPPFLAGS@ @LIBXML2_CFLAGS@ AM_CPPFLAGS += -I$(top_srcdir) spatialite_SOURCES = shell.c spatialite_tool_SOURCES = spatialite_tool.c spatialite_network_SOURCES = spatialite_network.c shp_doctor_SOURCES = shp_doctor.c +shp_sanitize_SOURCES = shp_sanitize.c exif_loader_SOURCES = exif_loader.c spatialite_xml_validator_SOURCES = spatialite_xml_validator.c spatialite_xml_load_SOURCES = spatialite_xml_load.c +spatialite_xml2utf8_SOURCES = spatialite_xml2utf8.c spatialite_xml_collapse_SOURCES = spatialite_xml_collapse.c spatialite_xml_print_SOURCES = spatialite_xml_print.c if NO_READOSM else spatialite_osm_net_SOURCES = spatialite_osm_net.c @@ -54,10 +60,11 @@ spatialite_osm_raw_SOURCES = spatialite_osm_raw.c endif spatialite_osm_filter_SOURCES = spatialite_osm_filter.c spatialite_gml_SOURCES = spatialite_gml.c spatialite_osm_overpass_SOURCES = spatialite_osm_overpass.c +spatialite_dem_SOURCES = spatialite_dem.c spatialite_osm_map_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ @LIBREADOSM_LIBS@ spatialite_osm_overpass_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ @LIBXML2_LIBS@ @@ -66,10 +73,11 @@ spatialite_osm_net_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ @LIBREADOSM_LIBS@ spatialite_gml_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ \ -lexpat +spatialite_dem_LDADD = @LIBSPATIALITE_LIBS@ spatialite_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ \ @READLINE_LIBS@ spatialite_xml_validator_LDADD = @LIBXML2_LIBS@ spatialite_xml_load_LDADD = @LIBSPATIALITE_LIBS@ \ @@ -80,10 +88,12 @@ @LIBFREEXL_LIBS@ EXTRA_DIST = makefile.vc nmake.opt \ config-msvc.h \ Makefile-static-MinGW \ + Makefile-static-mingw32 \ + Makefile-static-mingw64 \ Makefile-static-Linux \ Makefile-static-MacOsX -AUTOMAKE_OPTIONS = dist-zip +AUTOMAKE_OPTIONS = dist-zip foreign Index: Makefile.in ================================================================== --- Makefile.in +++ Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -13,11 +13,21 @@ # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ @@ -79,49 +89,52 @@ build_triplet = @build@ host_triplet = @host@ @NO_READOSM_FALSE@bin_PROGRAMS = spatialite$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_tool$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_network$(EXEEXT) \ -@NO_READOSM_FALSE@ shp_doctor$(EXEEXT) exif_loader$(EXEEXT) \ +@NO_READOSM_FALSE@ shp_doctor$(EXEEXT) shp_sanitize$(EXEEXT) \ +@NO_READOSM_FALSE@ exif_loader$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_osm_net$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_osm_map$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_osm_raw$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_osm_filter$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_gml$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_convert$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_dxf$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_xml_validator$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_xml_load$(EXEEXT) \ +@NO_READOSM_FALSE@ spatialite_xml2utf8$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_xml_collapse$(EXEEXT) \ @NO_READOSM_FALSE@ spatialite_xml_print$(EXEEXT) \ -@NO_READOSM_FALSE@ spatialite_osm_overpass$(EXEEXT) +@NO_READOSM_FALSE@ spatialite_osm_overpass$(EXEEXT) \ +@NO_READOSM_FALSE@ spatialite_dem$(EXEEXT) @NO_READOSM_TRUE@bin_PROGRAMS = spatialite$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_tool$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_network$(EXEEXT) \ -@NO_READOSM_TRUE@ shp_doctor$(EXEEXT) exif_loader$(EXEEXT) \ +@NO_READOSM_TRUE@ shp_doctor$(EXEEXT) shp_sanitize$(EXEEXT) \ +@NO_READOSM_TRUE@ exif_loader$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_osm_filter$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_gml$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_convert$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_dxf$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_xml_validator$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_xml_load$(EXEEXT) \ +@NO_READOSM_TRUE@ spatialite_xml2utf8$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_xml_collapse$(EXEEXT) \ @NO_READOSM_TRUE@ spatialite_xml_print$(EXEEXT) \ -@NO_READOSM_TRUE@ spatialite_osm_overpass$(EXEEXT) +@NO_READOSM_TRUE@ spatialite_osm_overpass$(EXEEXT) \ +@NO_READOSM_TRUE@ spatialite_dem$(EXEEXT) subdir = . -DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ - $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/config.h.in depcomp COPYING config.guess config.sub \ - install-sh missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = @@ -138,17 +151,24 @@ am__v_lt_1 = am_shp_doctor_OBJECTS = shp_doctor.$(OBJEXT) shp_doctor_OBJECTS = $(am_shp_doctor_OBJECTS) shp_doctor_LDADD = $(LDADD) shp_doctor_DEPENDENCIES = +am_shp_sanitize_OBJECTS = shp_sanitize.$(OBJEXT) +shp_sanitize_OBJECTS = $(am_shp_sanitize_OBJECTS) +shp_sanitize_LDADD = $(LDADD) +shp_sanitize_DEPENDENCIES = am_spatialite_OBJECTS = shell.$(OBJEXT) spatialite_OBJECTS = $(am_spatialite_OBJECTS) spatialite_DEPENDENCIES = spatialite_convert_SOURCES = spatialite_convert.c spatialite_convert_OBJECTS = spatialite_convert.$(OBJEXT) spatialite_convert_LDADD = $(LDADD) spatialite_convert_DEPENDENCIES = +am_spatialite_dem_OBJECTS = spatialite_dem.$(OBJEXT) +spatialite_dem_OBJECTS = $(am_spatialite_dem_OBJECTS) +spatialite_dem_DEPENDENCIES = spatialite_dxf_SOURCES = spatialite_dxf.c spatialite_dxf_OBJECTS = spatialite_dxf.$(OBJEXT) spatialite_dxf_LDADD = $(LDADD) spatialite_dxf_DEPENDENCIES = am_spatialite_gml_OBJECTS = spatialite_gml.$(OBJEXT) @@ -184,10 +204,14 @@ spatialite_osm_raw_DEPENDENCIES = am_spatialite_tool_OBJECTS = spatialite_tool.$(OBJEXT) spatialite_tool_OBJECTS = $(am_spatialite_tool_OBJECTS) spatialite_tool_LDADD = $(LDADD) spatialite_tool_DEPENDENCIES = +am_spatialite_xml2utf8_OBJECTS = spatialite_xml2utf8.$(OBJEXT) +spatialite_xml2utf8_OBJECTS = $(am_spatialite_xml2utf8_OBJECTS) +spatialite_xml2utf8_LDADD = $(LDADD) +spatialite_xml2utf8_DEPENDENCIES = am_spatialite_xml_collapse_OBJECTS = \ spatialite_xml_collapse.$(OBJEXT) spatialite_xml_collapse_OBJECTS = \ $(am_spatialite_xml_collapse_OBJECTS) spatialite_xml_collapse_DEPENDENCIES = @@ -236,28 +260,32 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(exif_loader_SOURCES) $(shp_doctor_SOURCES) \ - $(spatialite_SOURCES) spatialite_convert.c spatialite_dxf.c \ - $(spatialite_gml_SOURCES) $(spatialite_network_SOURCES) \ - $(spatialite_osm_filter_SOURCES) $(spatialite_osm_map_SOURCES) \ - $(spatialite_osm_net_SOURCES) \ + $(shp_sanitize_SOURCES) $(spatialite_SOURCES) \ + spatialite_convert.c $(spatialite_dem_SOURCES) \ + spatialite_dxf.c $(spatialite_gml_SOURCES) \ + $(spatialite_network_SOURCES) $(spatialite_osm_filter_SOURCES) \ + $(spatialite_osm_map_SOURCES) $(spatialite_osm_net_SOURCES) \ $(spatialite_osm_overpass_SOURCES) \ $(spatialite_osm_raw_SOURCES) $(spatialite_tool_SOURCES) \ + $(spatialite_xml2utf8_SOURCES) \ $(spatialite_xml_collapse_SOURCES) \ $(spatialite_xml_load_SOURCES) $(spatialite_xml_print_SOURCES) \ $(spatialite_xml_validator_SOURCES) DIST_SOURCES = $(exif_loader_SOURCES) $(shp_doctor_SOURCES) \ - $(spatialite_SOURCES) spatialite_convert.c spatialite_dxf.c \ - $(spatialite_gml_SOURCES) $(spatialite_network_SOURCES) \ - $(spatialite_osm_filter_SOURCES) \ + $(shp_sanitize_SOURCES) $(spatialite_SOURCES) \ + spatialite_convert.c $(spatialite_dem_SOURCES) \ + spatialite_dxf.c $(spatialite_gml_SOURCES) \ + $(spatialite_network_SOURCES) $(spatialite_osm_filter_SOURCES) \ $(am__spatialite_osm_map_SOURCES_DIST) \ $(am__spatialite_osm_net_SOURCES_DIST) \ $(spatialite_osm_overpass_SOURCES) \ $(am__spatialite_osm_raw_SOURCES_DIST) \ - $(spatialite_tool_SOURCES) $(spatialite_xml_collapse_SOURCES) \ + $(spatialite_tool_SOURCES) $(spatialite_xml2utf8_SOURCES) \ + $(spatialite_xml_collapse_SOURCES) \ $(spatialite_xml_load_SOURCES) $(spatialite_xml_print_SOURCES) \ $(spatialite_xml_validator_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -283,10 +311,13 @@ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope AM_RECURSIVE_TARGETS = cscope +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ + COPYING ChangeLog INSTALL NEWS README compile config.guess \ + config.sub depcomp install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ @@ -378,10 +409,12 @@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +RTTOPO_CFLAGS = @RTTOPO_CFLAGS@ +RTTOPO_LIBS = @RTTOPO_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ @@ -437,26 +470,29 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS = @CFLAGS@ @LIBXML2_CFLAGS@ -I$(top_srcdir) +AM_CPPFLAGS = @CFLAGS@ @CPPFLAGS@ @LIBXML2_CFLAGS@ -I$(top_srcdir) spatialite_SOURCES = shell.c spatialite_tool_SOURCES = spatialite_tool.c spatialite_network_SOURCES = spatialite_network.c shp_doctor_SOURCES = shp_doctor.c +shp_sanitize_SOURCES = shp_sanitize.c exif_loader_SOURCES = exif_loader.c spatialite_xml_validator_SOURCES = spatialite_xml_validator.c spatialite_xml_load_SOURCES = spatialite_xml_load.c +spatialite_xml2utf8_SOURCES = spatialite_xml2utf8.c spatialite_xml_collapse_SOURCES = spatialite_xml_collapse.c spatialite_xml_print_SOURCES = spatialite_xml_print.c @NO_READOSM_FALSE@spatialite_osm_net_SOURCES = spatialite_osm_net.c @NO_READOSM_FALSE@spatialite_osm_map_SOURCES = spatialite_osm_map.c @NO_READOSM_FALSE@spatialite_osm_raw_SOURCES = spatialite_osm_raw.c spatialite_osm_filter_SOURCES = spatialite_osm_filter.c spatialite_gml_SOURCES = spatialite_gml.c spatialite_osm_overpass_SOURCES = spatialite_osm_overpass.c +spatialite_dem_SOURCES = spatialite_dem.c spatialite_osm_map_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ @LIBREADOSM_LIBS@ spatialite_osm_overpass_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ @LIBXML2_LIBS@ @@ -469,10 +505,11 @@ spatialite_gml_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ \ -lexpat +spatialite_dem_LDADD = @LIBSPATIALITE_LIBS@ spatialite_LDADD = @LIBSPATIALITE_LIBS@ \ @LIBFREEXL_LIBS@ \ @READLINE_LIBS@ spatialite_xml_validator_LDADD = @LIBXML2_LIBS@ @@ -485,14 +522,16 @@ @LIBFREEXL_LIBS@ EXTRA_DIST = makefile.vc nmake.opt \ config-msvc.h \ Makefile-static-MinGW \ + Makefile-static-mingw32 \ + Makefile-static-mingw64 \ Makefile-static-Linux \ Makefile-static-MacOsX -AUTOMAKE_OPTIONS = dist-zip +AUTOMAKE_OPTIONS = dist-zip foreign all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -500,20 +539,19 @@ @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile + $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ @@ -530,12 +568,12 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) @@ -600,18 +638,26 @@ $(AM_V_CCLD)$(LINK) $(exif_loader_OBJECTS) $(exif_loader_LDADD) $(LIBS) shp_doctor$(EXEEXT): $(shp_doctor_OBJECTS) $(shp_doctor_DEPENDENCIES) $(EXTRA_shp_doctor_DEPENDENCIES) @rm -f shp_doctor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(shp_doctor_OBJECTS) $(shp_doctor_LDADD) $(LIBS) + +shp_sanitize$(EXEEXT): $(shp_sanitize_OBJECTS) $(shp_sanitize_DEPENDENCIES) $(EXTRA_shp_sanitize_DEPENDENCIES) + @rm -f shp_sanitize$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(shp_sanitize_OBJECTS) $(shp_sanitize_LDADD) $(LIBS) spatialite$(EXEEXT): $(spatialite_OBJECTS) $(spatialite_DEPENDENCIES) $(EXTRA_spatialite_DEPENDENCIES) @rm -f spatialite$(EXEEXT) $(AM_V_CCLD)$(LINK) $(spatialite_OBJECTS) $(spatialite_LDADD) $(LIBS) spatialite_convert$(EXEEXT): $(spatialite_convert_OBJECTS) $(spatialite_convert_DEPENDENCIES) $(EXTRA_spatialite_convert_DEPENDENCIES) @rm -f spatialite_convert$(EXEEXT) $(AM_V_CCLD)$(LINK) $(spatialite_convert_OBJECTS) $(spatialite_convert_LDADD) $(LIBS) + +spatialite_dem$(EXEEXT): $(spatialite_dem_OBJECTS) $(spatialite_dem_DEPENDENCIES) $(EXTRA_spatialite_dem_DEPENDENCIES) + @rm -f spatialite_dem$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(spatialite_dem_OBJECTS) $(spatialite_dem_LDADD) $(LIBS) spatialite_dxf$(EXEEXT): $(spatialite_dxf_OBJECTS) $(spatialite_dxf_DEPENDENCIES) $(EXTRA_spatialite_dxf_DEPENDENCIES) @rm -f spatialite_dxf$(EXEEXT) $(AM_V_CCLD)$(LINK) $(spatialite_dxf_OBJECTS) $(spatialite_dxf_LDADD) $(LIBS) @@ -644,10 +690,14 @@ $(AM_V_CCLD)$(LINK) $(spatialite_osm_raw_OBJECTS) $(spatialite_osm_raw_LDADD) $(LIBS) spatialite_tool$(EXEEXT): $(spatialite_tool_OBJECTS) $(spatialite_tool_DEPENDENCIES) $(EXTRA_spatialite_tool_DEPENDENCIES) @rm -f spatialite_tool$(EXEEXT) $(AM_V_CCLD)$(LINK) $(spatialite_tool_OBJECTS) $(spatialite_tool_LDADD) $(LIBS) + +spatialite_xml2utf8$(EXEEXT): $(spatialite_xml2utf8_OBJECTS) $(spatialite_xml2utf8_DEPENDENCIES) $(EXTRA_spatialite_xml2utf8_DEPENDENCIES) + @rm -f spatialite_xml2utf8$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(spatialite_xml2utf8_OBJECTS) $(spatialite_xml2utf8_LDADD) $(LIBS) spatialite_xml_collapse$(EXEEXT): $(spatialite_xml_collapse_OBJECTS) $(spatialite_xml_collapse_DEPENDENCIES) $(EXTRA_spatialite_xml_collapse_DEPENDENCIES) @rm -f spatialite_xml_collapse$(EXEEXT) $(AM_V_CCLD)$(LINK) $(spatialite_xml_collapse_OBJECTS) $(spatialite_xml_collapse_LDADD) $(LIBS) @@ -670,20 +720,23 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exif_loader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shell.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shp_doctor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shp_sanitize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_convert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_dem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_dxf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_gml.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_network.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_osm_filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_osm_map.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_osm_net.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_osm_overpass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_osm_raw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_tool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_xml2utf8.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_xml_collapse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_xml_load.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_xml_print.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spatialite_xml_validator.Po@am__quote@ @@ -690,18 +743,18 @@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -814,11 +867,11 @@ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) @@ -830,15 +883,21 @@ dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) @@ -851,36 +910,37 @@ # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ @@ -1057,10 +1117,12 @@ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS + +.PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Index: aclocal.m4 ================================================================== --- aclocal.m4 +++ aclocal.m4 @@ -1,8 +1,8 @@ -# generated automatically by aclocal 1.13.4 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -18,36 +18,67 @@ [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 1 (pkg-config-0.24) -# -# Copyright © 2004 Scott James Remnant . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) @@ -65,33 +96,36 @@ else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl -])# PKG_PROG_PKG_CONFIG +])dnl PKG_PROG_PKG_CONFIG -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -# only at the first occurence in configure.ac, so if the first place -# it's called might be skipped (such as if it is within an "if", you -# have to call PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], @@ -99,34 +133,33 @@ test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl -])# _PKG_CONFIG +])dnl _PKG_CONFIG -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED +])dnl _PKG_SHORT_ERRORS_SUPPORTED -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl @@ -176,20 +209,44 @@ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl -])# PKG_CHECK_MODULES +])dnl PKG_CHECK_MODULES -# PKG_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable pkgconfigdir as the location where a module -# should install pkg-config .pc files. By default the directory is -# $libdir/pkgconfig, but the default can be changed by passing -# DIRECTORY. The user can override through the --with-pkgconfigdir -# parameter. +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], @@ -196,20 +253,22 @@ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -]) dnl PKG_INSTALLDIR +])dnl PKG_INSTALLDIR -# PKG_NOARCH_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable noarch_pkgconfigdir as the location where a -# module should install arch-independent pkg-config .pc files. By -# default the directory is $datadir/pkgconfig, but the default can be -# changed by passing DIRECTORY. The user can override through the -# --with-noarch-pkgconfigdir parameter. +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], @@ -216,28 +275,30 @@ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -]) dnl PKG_NOARCH_INSTALLDIR +])dnl PKG_NOARCH_INSTALLDIR -# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# ------------------------------------------- -# Retrieves the value of the pkg-config variable for the given module. +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl -])# PKG_CHECK_VAR +])dnl PKG_CHECK_VAR -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -245,14 +306,14 @@ # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.13' +[am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.13.4], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- @@ -264,18 +325,18 @@ # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.13.4])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -316,19 +377,18 @@ # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -355,11 +415,11 @@ [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -546,11 +606,11 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -622,18 +682,24 @@ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style @@ -706,12 +772,12 @@ # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], @@ -739,18 +805,62 @@ dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -769,11 +879,11 @@ _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -780,21 +890,21 @@ # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -812,11 +922,11 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -847,11 +957,11 @@ ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -897,11 +1007,11 @@ rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -938,11 +1048,11 @@ # -*- Autoconf -*- # Obsolete and "removed" macros, that must however still report explicit # error messages when used, to smooth transition. # -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -965,11 +1075,11 @@ [AC_FATAL([automatic de-ANSI-fication support has been removed])]) AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -993,14 +1103,78 @@ # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -1077,11 +1251,11 @@ fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) -# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -1137,11 +1311,11 @@ AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -1165,11 +1339,11 @@ AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -1184,11 +1358,11 @@ # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. ADDED compile Index: compile ================================================================== --- compile +++ compile @@ -0,0 +1,1 @@ +/usr/share/automake-1.15/compile Index: config.h ================================================================== --- config.h +++ config.h @@ -1,10 +1,13 @@ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Should be defined in order to enable LIBXML2 support. */ #define ENABLE_LIBXML2 1 + +/* Should be defined in order to enable RTTOPO support. */ +#define ENABLE_RTTOPO 1 /* depending on SQLite library version. */ #define HAVE_DECL_SQLITE_CONFIG_URI 1 /* depending on SQLite library version. */ @@ -85,10 +88,13 @@ /* Define to 1 if you have the `expat' library (-lexpat). */ #define HAVE_LIBEXPAT 1 /* Define to 1 if you have the `proj' library (-lproj). */ #define HAVE_LIBPROJ 1 + +/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */ +#define HAVE_LIBSQLITE3 1 /* Define to 1 if you have the `localtime_r' function. */ #define HAVE_LOCALTIME_R 1 /* Define to 1 if `lstat' has the bug that it succeeds when given the @@ -107,10 +113,16 @@ /* Define to 1 if you have the `memset' function. */ #define HAVE_MEMSET 1 /* Define to 1 if you have the `readline' function. */ #define HAVE_READLINE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SQLITE3EXT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SQLITE3_H 1 /* Define to 1 if you have the `sqrt' function. */ /* #undef HAVE_SQRT */ /* Define to 1 if `stat' has the bug that it succeeds when given the @@ -184,20 +196,20 @@ /* Define to the full name of this package. */ #define PACKAGE_NAME "spatialite-tools" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "spatialite-tools 4.2.1-rc1" +#define PACKAGE_STRING "spatialite-tools 4.5.0-devel" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "spatialite-tools" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "4.2.1-rc1" +#define PACKAGE_VERSION "4.5.0-devel" /* must be defined when using libspatialite-amalgamation */ /* #undef SPATIALITE_AMALGAMATION */ /* Define to 1 if you have the ANSI C header files. */ @@ -208,11 +220,11 @@ /* Define to 1 if your declares `struct tm'. */ /* #undef TM_IN_SYS_TIME */ /* Version number of package */ -#define VERSION "4.2.1-rc1" +#define VERSION "4.5.0-devel" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `long int' if does not define. */ Index: config.h.in ================================================================== --- config.h.in +++ config.h.in @@ -1,9 +1,12 @@ /* config.h.in. Generated from configure.ac by autoheader. */ /* Should be defined in order to enable LIBXML2 support. */ #undef ENABLE_LIBXML2 + +/* Should be defined in order to enable RTTOPO support. */ +#undef ENABLE_RTTOPO /* depending on SQLite library version. */ #undef HAVE_DECL_SQLITE_CONFIG_URI /* depending on SQLite library version. */ @@ -84,10 +87,13 @@ /* Define to 1 if you have the `expat' library (-lexpat). */ #undef HAVE_LIBEXPAT /* Define to 1 if you have the `proj' library (-lproj). */ #undef HAVE_LIBPROJ + +/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */ +#undef HAVE_LIBSQLITE3 /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R /* Define to 1 if `lstat' has the bug that it succeeds when given the @@ -106,10 +112,16 @@ /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `readline' function. */ #undef HAVE_READLINE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SQLITE3EXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SQLITE3_H /* Define to 1 if you have the `sqrt' function. */ #undef HAVE_SQRT /* Define to 1 if `stat' has the bug that it succeeds when given the Index: configure ================================================================== --- configure +++ configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for spatialite-tools 4.2.1-rc1. +# Generated by GNU Autoconf 2.69 for spatialite-tools 4.5.0-devel. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -588,12 +588,12 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='spatialite-tools' PACKAGE_TARNAME='spatialite-tools' -PACKAGE_VERSION='4.2.1-rc1' -PACKAGE_STRING='spatialite-tools 4.2.1-rc1' +PACKAGE_VERSION='4.5.0-devel' +PACKAGE_STRING='spatialite-tools 4.5.0-devel' PACKAGE_BUGREPORT='a.furieri@lqt.it' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ @@ -632,10 +632,12 @@ #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS +RTTOPO_LIBS +RTTOPO_CFLAGS LIBXML2_LIBS LIBXML2_CFLAGS NO_READOSM_FALSE NO_READOSM_TRUE LIBREADOSM_CFLAGS @@ -791,10 +793,11 @@ enable_readline with_geosconfig enable_freexl enable_readosm enable_libxml2 +enable_rttopo ' ac_precious_vars='build_alias host_alias target_alias CC @@ -815,11 +818,13 @@ LIBFREEXL_CFLAGS LIBFREEXL_LIBS LIBREADOSM_CFLAGS LIBREADOSM_LIBS LIBXML2_CFLAGS -LIBXML2_LIBS' +LIBXML2_LIBS +RTTOPO_CFLAGS +RTTOPO_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false @@ -1356,11 +1361,11 @@ # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures spatialite-tools 4.2.1-rc1 to adapt to many kinds of systems. +\`configure' configures spatialite-tools 4.5.0-devel to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. @@ -1427,11 +1432,11 @@ _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of spatialite-tools 4.2.1-rc1:";; + short | recursive ) echo "Configuration of spatialite-tools 4.5.0-devel:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options @@ -1453,10 +1458,11 @@ --disable-libtool-lock avoid locking (might break parallel builds) --enable-readline use readline in shell tool (yes, no) [default=yes] --enable-freexl enables FreeXL inclusion [default=yes] --enable-readosm enables ReadOSM inclusion [default=yes] --enable-libxml2 enables libxml2 inclusion [default=yes] + --enable-rttopo enables librttopo inclusion [default=yes] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic try to use only PIC/non-PIC objects [default=use @@ -1497,10 +1503,13 @@ linker flags for LIBREADOSM, overriding pkg-config LIBXML2_CFLAGS C compiler flags for LIBXML2, overriding pkg-config LIBXML2_LIBS linker flags for LIBXML2, overriding pkg-config + RTTOPO_CFLAGS + C compiler flags for RTTOPO, overriding pkg-config + RTTOPO_LIBS linker flags for RTTOPO, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . @@ -1564,11 +1573,11 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -spatialite-tools configure 4.2.1-rc1 +spatialite-tools configure 4.5.0-devel generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -2154,11 +2163,11 @@ } # ac_fn_c_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by spatialite-tools $as_me 4.2.1-rc1, which was +It was created by spatialite-tools $as_me 4.5.0-devel, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF @@ -2510,11 +2519,11 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -am__api_version='1.13' +am__api_version='1.15' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir @@ -2711,12 +2720,12 @@ # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; @@ -2731,11 +2740,11 @@ am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" @@ -3025,11 +3034,11 @@ fi # Define the identity of the package. PACKAGE='spatialite-tools' - VERSION='4.2.1-rc1' + VERSION='4.5.0-devel' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF @@ -3059,12 +3068,12 @@ # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' @@ -3075,10 +3084,52 @@ + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. @@ -3103,10 +3154,11 @@ ac_config_headers="$ac_config_headers config.h" # supporting SPATIALITE_AMALGAMATION + @@ -3977,10 +4029,69 @@ ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } @@ -4669,10 +4780,38 @@ _ACEOF else as_fn_error $? "cannot find unistd.h, bailing out" "$LINENO" 5 fi + +done + +for ac_header in sqlite3.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default" +if test "x$ac_cv_header_sqlite3_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SQLITE3_H 1 +_ACEOF + +else + as_fn_error $? "cannot find sqlite3.h, bailing out" "$LINENO" 5 +fi + +done + +for ac_header in sqlite3ext.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sqlite3ext.h" "ac_cv_header_sqlite3ext_h" "$ac_includes_default" +if test "x$ac_cv_header_sqlite3ext_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SQLITE3EXT_H 1 +_ACEOF + +else + as_fn_error $? "cannot find sqlite3ext.h, bailing out" "$LINENO" 5 +fi done # Checks for programs. @@ -5597,10 +5736,69 @@ ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } @@ -17085,10 +17283,59 @@ _ACEOF fi done + +# Checks for installed libraries +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_prepare_v2 in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_prepare_v2 in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_prepare_v2+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_prepare_v2 (); +int +main () +{ +return sqlite3_prepare_v2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_prepare_v2=yes +else + ac_cv_lib_sqlite3_sqlite3_prepare_v2=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_prepare_v2" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_prepare_v2" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_prepare_v2" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + as_fn_error $? "'libsqlite3' is required but it doesn't seem to be installed on this system." "$LINENO" 5 +fi + ac_config_files="$ac_config_files Makefile" #----------------------------------------------------------------------- @@ -17868,10 +18115,68 @@ LIBREADOSM_LIBS=$pkg_cv_LIBREADOSM_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing readosm_version" >&5 +$as_echo_n "checking for library containing readosm_version... " >&6; } +if ${ac_cv_search_readosm_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readosm_version (); +int +main () +{ +return readosm_version (); + ; + return 0; +} +_ACEOF +for ac_lib in '' readosm; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_readosm_version=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_readosm_version+:} false; then : + break +fi +done +if ${ac_cv_search_readosm_version+:} false; then : + +else + ac_cv_search_readosm_version=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_readosm_version" >&5 +$as_echo "$ac_cv_search_readosm_version" >&6; } +ac_res=$ac_cv_search_readosm_version +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "'libreadosm' (>= v.1.1.0) is required but an older version was found." "$LINENO" 5 +fi + else $as_echo "#define OMIT_READOSM 1" >>confdefs.h @@ -17971,10 +18276,98 @@ fi $as_echo "#define ENABLE_LIBXML2 1" >>confdefs.h +fi + +#----------------------------------------------------------------------- +# --enable-rttopo +# +# Check whether --enable-rttopo was given. +if test "${enable_rttopo+set}" = set; then : + enableval=$enable_rttopo; +else + enable_rttopo=yes +fi + +if test x"$enable_rttopo" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RTTOPO" >&5 +$as_echo_n "checking for RTTOPO... " >&6; } + +if test -n "$RTTOPO_CFLAGS"; then + pkg_cv_RTTOPO_CFLAGS="$RTTOPO_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rttopo\""; } >&5 + ($PKG_CONFIG --exists --print-errors "rttopo") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_RTTOPO_CFLAGS=`$PKG_CONFIG --cflags "rttopo" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$RTTOPO_LIBS"; then + pkg_cv_RTTOPO_LIBS="$RTTOPO_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rttopo\""; } >&5 + ($PKG_CONFIG --exists --print-errors "rttopo") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_RTTOPO_LIBS=`$PKG_CONFIG --libs "rttopo" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + RTTOPO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "rttopo" 2>&1` + else + RTTOPO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "rttopo" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$RTTOPO_PKG_ERRORS" >&5 + + as_fn_error $? "'librttopo' is required but it doesn't seem to be installed on this system." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "'librttopo' is required but it doesn't seem to be installed on this system." "$LINENO" 5 +else + RTTOPO_CFLAGS=$pkg_cv_RTTOPO_CFLAGS + RTTOPO_LIBS=$pkg_cv_RTTOPO_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + + $as_echo "#define ENABLE_RTTOPO 1" >>confdefs.h + fi # checks for SQLite version-depending constants ac_fn_c_check_decl "$LINENO" "SQLITE_CONFIG_URI" "ac_cv_have_decl_SQLITE_CONFIG_URI" "#include " @@ -18632,11 +19025,11 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by spatialite-tools $as_me 4.2.1-rc1, which was +This file was extended by spatialite-tools $as_me 4.5.0-devel, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS @@ -18698,11 +19091,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -spatialite-tools config.status 4.2.1-rc1 +spatialite-tools config.status 4.5.0-devel configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1,10 +1,10 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT(spatialite-tools, 4.2.1-rc1, a.furieri@lqt.it) +AC_INIT(spatialite-tools, 4.5.0-devel, a.furieri@lqt.it) AC_LANG(C) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE @@ -17,10 +17,12 @@ [Should be defined in order to disable FREEXL support.]) AH_TEMPLATE([OMIT_READOSM], [Should be defined in order to disable ReadOSM support.]) AH_TEMPLATE([ENABLE_LIBXML2], [Should be defined in order to enable LIBXML2 support.]) +AH_TEMPLATE([ENABLE_RTTOPO], + [Should be defined in order to enable RTTOPO support.]) AH_TEMPLATE([HAVE_DECL_SQLITE_CONFIG_URI], [depending on SQLite library version.]) AH_TEMPLATE([HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_USED], [depending on SQLite library version.]) AH_TEMPLATE([HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_HIT], @@ -65,10 +67,12 @@ AC_CHECK_HEADERS(inttypes.h,, [AC_MSG_ERROR([cannot find inttypes.h, bailing out])]) AC_CHECK_HEADERS(stddef.h,, [AC_MSG_ERROR([cannot find stddef.h, bailing out])]) AC_CHECK_HEADERS(stdint.h,, [AC_MSG_ERROR([cannot find stdint.h, bailing out])]) AC_CHECK_HEADERS(sys/time.h,, [AC_MSG_ERROR([cannot find sys/time.h, bailing out])]) AC_CHECK_HEADERS(unistd.h,, [AC_MSG_ERROR([cannot find unistd.h, bailing out])]) +AC_CHECK_HEADERS(sqlite3.h,, [AC_MSG_ERROR([cannot find sqlite3.h, bailing out])]) +AC_CHECK_HEADERS(sqlite3ext.h,, [AC_MSG_ERROR([cannot find sqlite3ext.h, bailing out])]) # Checks for programs. AC_PROG_CXX AC_PROG_CC AC_PROG_CPP @@ -91,10 +95,13 @@ AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK AC_FUNC_MEMCMP AC_FUNC_STAT AC_FUNC_STRFTIME AC_CHECK_FUNCS([memset sqrt strcasecmp strerror strncasecmp strstr fdatasync ftruncate getcwd gettimeofday localtime_r memmove strerror]) + +# Checks for installed libraries +AC_CHECK_LIB(sqlite3,sqlite3_prepare_v2,,AC_MSG_ERROR(['libsqlite3' is required but it doesn't seem to be installed on this system.]),-lm) AC_CONFIG_FILES([Makefile]) #----------------------------------------------------------------------- # --enable-readline @@ -188,10 +195,11 @@ AC_ARG_ENABLE(readosm, [AS_HELP_STRING( [--enable-readosm], [enables ReadOSM inclusion [default=yes]])], [], [enable_readosm=yes]) if test x"$enable_readosm" != "xno"; then AC_SUBST(LIBREADOSM_LIBS)PKG_CHECK_MODULES([LIBREADOSM], [readosm], , AC_MSG_ERROR(['libreadosm' is required but it doesn't seem to be installed on this system.])) + AC_SEARCH_LIBS(readosm_version,readosm,,AC_MSG_ERROR(['libreadosm' (>= v.1.1.0) is required but an older version was found.])) AC_SUBST(LIBREADOSM_CFLAGS) AC_SUBST(LIBREADOSM_LIBS) else AC_DEFINE(OMIT_READOSM) NOREADOSM="true" @@ -209,10 +217,23 @@ PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], , AC_MSG_ERROR(['libxml2' is required but it doesn't seem to be installed on this system.])) AC_SUBST(LIBXML2_CFLAGS) AC_SUBST(LIBXML2_LIBS) AC_DEFINE(ENABLE_LIBXML2) fi + +#----------------------------------------------------------------------- +# --enable-rttopo +# +AC_ARG_ENABLE(rttopo, [AS_HELP_STRING( + [--enable-rttopo], [enables librttopo inclusion [default=yes]])], + [], [enable_rttopo=yes]) +if test x"$enable_rttopo" != "xno"; then + PKG_CHECK_MODULES([RTTOPO], [rttopo], , AC_MSG_ERROR(['librttopo' is required but it doesn't seem to be installed on this system.])) + AC_SUBST(RTTOPO_CFLAGS) + AC_SUBST(RTTOPO_LIBS) + AC_DEFINE(ENABLE_RTTOPO) +fi # checks for SQLite version-depending constants AC_CHECK_DECL([SQLITE_CONFIG_URI], [AC_DEFINE(HAVE_DECL_SQLITE_CONFIG_URI)],[],[[#include ]]) AC_CHECK_DECL([SQLITE_DBSTATUS_LOOKASIDE_USED], Index: exif_loader.c ================================================================== --- exif_loader.c +++ exif_loader.c @@ -1427,19 +1427,32 @@ if (count > 0) return; /* all right, it's empty: proceeding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "exif_loader .: %s\n", VERSION); + fprintf (stderr, "target CPU ..: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ..: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -1446,10 +1459,11 @@ fprintf (stderr, "\n\nusage: exif_loader ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite db path\n"); fprintf (stderr, "-D or --dir dir_path the DIR path containing EXIF files\n"); fprintf (stderr, "-f or --file-path file_name a single EXIF file\n\n"); @@ -1499,10 +1513,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcasecmp (argv[i], "--db-path") == 0) { next_arg = ARG_DB_PATH; continue; @@ -1615,8 +1635,8 @@ spatialite_cleanup_ex (cache); if (cnt) fprintf (stderr, "\n\n*** %d EXIF photo%s successfully inserted into the DB\n", cnt, (cnt > 1) ? "s where" : " was"); -spatialite_shutdown(); + spatialite_shutdown (); return 0; } Index: makefile.vc ================================================================== --- makefile.vc +++ makefile.vc @@ -5,10 +5,11 @@ !INCLUDE nmake.opt SPATIALITE_EXE = spatialite.exe EXIF_LOADER_EXE = exif_loader.exe SHP_DOCTOR_EXE = shp_doctor.exe +SHP_SANITIZE_EXE = shp_sanitize.exe SPATIALITE_NETWORK_EXE = spatialite_network.exe SPATIALITE_TOOL_EXE = spatialite_tool.exe SPATIALITE_OSM_NET_EXE = spatialite_osm_net.exe SPATIALITE_OSM_MAP_EXE = spatialite_osm_map.exe SPATIALITE_OSM_RAW_EXE = spatialite_osm_raw.exe @@ -21,11 +22,11 @@ all: $(SPATIALITE_EXE) $(SHP_DOCTOR_EXE) $(SPATIALITE_TOOL_EXE) \ $(SPATIALITE_NETWORK_EXE) $(EXIF_LOADER_EXE) \ $(SPATIALITE_OSM_NET_EXE) $(SPATIALITE_OSM_MAP_EXE) \ $(SPATIALITE_GML_EXE) $(SPATIALITE_OSM_RAW_EXE) \ - $(SPATIALITE_OSM_FILTER_EXE) + $(SPATIALITE_OSM_FILTER_EXE) $(SHP_SANITIZE_EXE) $(SPATIALITE_EXE): shell.obj cl shell.obj C:\OSGeo4W\lib\proj_i.lib \ C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib \ @@ -45,10 +46,17 @@ C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib if exist $(SHP_DOCTOR_EXE).manifest mt -manifest \ $(SHP_DOCTOR_EXE).manifest -outputresource:$(SHP_DOCTOR_EXE);1 +$(SHP_SANITIZE_EXE): shp_sanitize.obj + cl shp_sanitize.obj C:\OSGeo4W\lib\proj_i.lib \ + C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ + C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib + if exist $(SHP_SANITIZE_EXE).manifest mt -manifest \ + $(SHP_SANITIZE_EXE).manifest -outputresource:$(SHP_SANITIZE_EXE);1 + $(SPATIALITE_NETWORK_EXE): spatialite_network.obj cl spatialite_network.obj C:\OSGeo4W\lib\proj_i.lib \ C:\OSGeo4W\lib\iconv.lib \ C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib if exist $(SPATIALITE_NETWORK_EXE).manifest mt -manifest \ Index: shell.c ================================================================== --- shell.c +++ shell.c @@ -69,45 +69,45 @@ #ifdef _WIN32 #define strcasecmp _stricmp #endif /* not WIN32 */ #if !defined(_WIN32) && !defined(WIN32) -# include -# if !defined(__RTP__) && !defined(_WRS_KERNEL) -# include -# endif -# include -# include +#include +#if !defined(__RTP__) && !defined(_WRS_KERNEL) +#include +#endif +#include +#include #endif #ifdef HAVE_EDITLINE -# include +#include #endif #if defined(HAVE_READLINE) && HAVE_READLINE==1 -# include -# include +#include +#include #endif #if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1) -# define readline(p) local_getline(p,stdin,0) -# define add_history(X) -# define read_history(X) -# define write_history(X) -# define stifle_history(X) +#define readline(p) local_getline(p,stdin,0) +#define add_history(X) +#define read_history(X) +#define write_history(X) +#define stifle_history(X) #endif #if defined(_WIN32) || defined(WIN32) -# include +#include #define isatty(h) _isatty(h) #define access(f,m) _access((f),(m)) #undef popen #define popen(a,b) _popen((a),(b)) #undef pclose #define pclose(x) _pclose(x) #else /* Make sure isatty() has a prototype. */ -extern int isatty(int); +extern int isatty (int); #endif #if defined(_WIN32_WCE) /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be @@ -136,33 +136,41 @@ static struct rusage sBegin; /* ** Begin timing an operation */ -static void beginTimer(void){ - if( enableTimer ){ - getrusage(RUSAGE_SELF, &sBegin); - } +static void +beginTimer (void) +{ + if (enableTimer) + { + getrusage (RUSAGE_SELF, &sBegin); + } } /* Return the difference of two time_structs in seconds */ -static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + - (double)(pEnd->tv_sec - pStart->tv_sec); +static double +timeDiff (struct timeval *pStart, struct timeval *pEnd) +{ + return (pEnd->tv_usec - pStart->tv_usec) * 0.000001 + + (double) (pEnd->tv_sec - pStart->tv_sec); } /* ** Print the timing results. */ -static void endTimer(void){ - if( enableTimer ){ - struct rusage sEnd; - getrusage(RUSAGE_SELF, &sEnd); - printf("CPU Time: user %f sys %f\n", - timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), - timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); - } +static void +endTimer (void) +{ + if (enableTimer) + { + struct rusage sEnd; + getrusage (RUSAGE_SELF, &sEnd); + printf ("CPU Time: user %f sys %f\n", + timeDiff (&sBegin.ru_utime, &sEnd.ru_utime), + timeDiff (&sBegin.ru_stime, &sEnd.ru_stime)); + } } #define BEGIN_TIMER beginTimer() #define END_TIMER endTimer() #define HAS_TIMER 1 @@ -173,76 +181,97 @@ /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; static FILETIME ftKernelBegin; static FILETIME ftUserBegin; -typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); +typedef BOOL (WINAPI * GETPROCTIMES) (HANDLE, LPFILETIME, LPFILETIME, + LPFILETIME, LPFILETIME); static GETPROCTIMES getProcessTimesAddr = NULL; /* ** Check to see if we have timer support. Return 1 if necessary ** support found (or found previously). */ -static int hasTimer(void){ - if( getProcessTimesAddr ){ - return 1; - } else { - /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions. - ** See if the version we are running on has it, and if it does, save off - ** a pointer to it and the current process handle. - */ - hProcess = GetCurrentProcess(); - if( hProcess ){ - HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); - if( NULL != hinstLib ){ - getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); - if( NULL != getProcessTimesAddr ){ - return 1; - } - FreeLibrary(hinstLib); - } - } - } - return 0; -} - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer && getProcessTimesAddr ){ - FILETIME ftCreation, ftExit; - getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin); - } +static int +hasTimer (void) +{ + if (getProcessTimesAddr) + { + return 1; + } + else + { + /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions. + ** See if the version we are running on has it, and if it does, save off + ** a pointer to it and the current process handle. + */ + hProcess = GetCurrentProcess (); + if (hProcess) + { + HINSTANCE hinstLib = LoadLibrary (TEXT ("Kernel32.dll")); + if (NULL != hinstLib) + { + getProcessTimesAddr = + (GETPROCTIMES) GetProcAddress (hinstLib, + "GetProcessTimes"); + if (NULL != getProcessTimesAddr) + { + return 1; + } + FreeLibrary (hinstLib); + } + } + } + return 0; +} + +/* +** Begin timing an operation +*/ +static void +beginTimer (void) +{ + if (enableTimer && getProcessTimesAddr) + { + FILETIME ftCreation, ftExit; + getProcessTimesAddr (hProcess, &ftCreation, &ftExit, &ftKernelBegin, + &ftUserBegin); + } } /* Return the difference of two FILETIME structs in seconds */ -static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ - sqlite_int64 i64Start = *((sqlite_int64 *) pStart); - sqlite_int64 i64End = *((sqlite_int64 *) pEnd); - return (double) ((i64End - i64Start) / 10000000.0); +static double +timeDiff (FILETIME * pStart, FILETIME * pEnd) +{ + sqlite_int64 i64Start = *((sqlite_int64 *) pStart); + sqlite_int64 i64End = *((sqlite_int64 *) pEnd); + return (double) ((i64End - i64Start) / 10000000.0); } /* ** Print the timing results. */ -static void endTimer(void){ - if( enableTimer && getProcessTimesAddr){ - FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; - getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd); - printf("CPU Time: user %f sys %f\n", - timeDiff(&ftUserBegin, &ftUserEnd), - timeDiff(&ftKernelBegin, &ftKernelEnd)); - } +static void +endTimer (void) +{ + if (enableTimer && getProcessTimesAddr) + { + FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; + getProcessTimesAddr (hProcess, &ftCreation, &ftExit, &ftKernelEnd, + &ftUserEnd); + printf ("CPU Time: user %f sys %f\n", + timeDiff (&ftUserBegin, &ftUserEnd), timeDiff (&ftKernelBegin, + &ftKernelEnd)); + } } #define BEGIN_TIMER beginTimer() #define END_TIMER endTimer() #define HAS_TIMER hasTimer() #else -#define BEGIN_TIMER +#define BEGIN_TIMER #define END_TIMER #define HAS_TIMER 0 #endif /* sandro: 3 September 2012 @@ -295,12 +324,12 @@ /* ** Prompt strings. Initialized in main. Settable with ** .prompt main continue */ -static char mainPrompt[20]; /* First line prompt. default: "spatialite> "*/ -static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ +static char mainPrompt[20]; /* First line prompt. default: "spatialite> " */ +static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ /* ** Write I/O traces to the following stream. */ #ifdef SQLITE_ENABLE_IOTRACE @@ -312,35 +341,41 @@ ** format string and subsequent arguments are values to be substituted ** in place of % fields. The result of formatting this string ** is written to iotrace. */ #ifdef SQLITE_ENABLE_IOTRACE -static void iotracePrintf(const char *zFormat, ...){ - va_list ap; - char *z; - if( iotrace==0 ) return; - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - fprintf(iotrace, "%s", z); - sqlite3_free(z); +static void +iotracePrintf (const char *zFormat, ...) +{ + va_list ap; + char *z; + if (iotrace == 0) + return; + va_start (ap, zFormat); + z = sqlite3_vmprintf (zFormat, ap); + va_end (ap); + fprintf (iotrace, "%s", z); + sqlite3_free (z); } #endif /* Sandro Furieri 2013-04-29 WFS progress handler callback */ -static void wfs_page_done(int features, void *ptr) +static void +wfs_page_done (int features, void *ptr) { + if (ptr != NULL) + ptr = NULL; /* silencing stupid compiler warnings */ if (isatty (1)) - { - printf("WFS Features loaded since now: %d\r", features); - fflush(stdout); - } + { + printf ("WFS Features loaded since now: %d\r", features); + fflush (stdout); + } } /* Sandro Furieri 2008-11-20 implementing AUTO FDO @@ -722,40 +757,41 @@ free (utf8buf); } /* sandro 2013-11-17 */ static void -split_drop_name(const char *str, char **prefix, char **table) +split_drop_name (const char *str, char **prefix, char **table) { int len1; int len2; const char *pt = NULL; const char *p = str; *prefix = NULL; *table = NULL; while (*p != '\0') - { - if (*p == '.') - { - pt = p; - break; - } - p++; - } + { + if (*p == '.') + { + pt = p; + break; + } + p++; + } if (pt == NULL) - return; + return; len1 = pt - str; - len2 = strlen(pt + 1); + len2 = strlen (pt + 1); if (len1 > 0 && len2 > 0) - { - *prefix = malloc(len1 + 1); - memcpy(*prefix, str, len1); - *(*prefix + len1) = '\0'; - *table = malloc(len2 + 1); - strcpy(*table, pt + 1); - } + { + *prefix = malloc (len1 + 1); + memcpy (*prefix, str, len1); + *(*prefix + len1) = '\0'; + *table = malloc (len2 + 1); + strcpy (*table, pt + 1); + } } + /* end sandro 2013-11-17 */ static void convert_input_to_utf8 (char *buf, int maxlen) { @@ -799,32 +835,53 @@ /* ** Determines if a string is a number of not. */ -static int isNumber(const char *z, int *realnum){ - if( *z=='-' || *z=='+' ) z++; - if( !IsDigit(*z) ){ - return 0; - } - z++; - if( realnum ) *realnum = 0; - while( IsDigit(*z) ){ z++; } - if( *z=='.' ){ +static int +isNumber (const char *z, int *realnum) +{ + if (*z == '-' || *z == '+') + z++; + if (!IsDigit (*z)) + { + return 0; + } z++; - if( !IsDigit(*z) ) return 0; - while( IsDigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z++; - if( *z=='+' || *z=='-' ) z++; - if( !IsDigit(*z) ) return 0; - while( IsDigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - return *z==0; + if (realnum) + *realnum = 0; + while (IsDigit (*z)) + { + z++; + } + if (*z == '.') + { + z++; + if (!IsDigit (*z)) + return 0; + while (IsDigit (*z)) + { + z++; + } + if (realnum) + *realnum = 1; + } + if (*z == 'e' || *z == 'E') + { + z++; + if (*z == '+' || *z == '-') + z++; + if (!IsDigit (*z)) + return 0; + while (IsDigit (*z)) + { + z++; + } + if (realnum) + *realnum = 1; + } + return *z == 0; } /* ** A global char* and an SQL function to access its current value ** from within an SQL statement. This program used to use the @@ -832,20 +889,18 @@ ** The correct way to do this with sqlite3 is to use the bind API, but ** since the shell is built around the callback paradigm it would be a lot ** of work. Instead just use this hack, which is quite harmless. */ static const char *zShellStatic = 0; -static void shellstaticFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - assert( 0==argc ); - assert( zShellStatic ); - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); +static void +shellstaticFunc (sqlite3_context * context, int argc, sqlite3_value ** argv) +{ + assert (0 == argc); + assert (zShellStatic); + UNUSED_PARAMETER (argc); + UNUSED_PARAMETER (argv); + sqlite3_result_text (context, zShellStatic, -1, SQLITE_STATIC); } /* ** This routine reads a line of text from FILE in, stores @@ -854,139 +909,161 @@ ** fails. ** ** The interface is like "readline" but no command-line editing ** is done. */ -static char *local_getline(char *zPrompt, FILE *in, int csvFlag){ - char *zLine; - int nLine; - int n; - int inQuote = 0; - - if( zPrompt && *zPrompt ){ - printf("%s",zPrompt); - fflush(stdout); - } - nLine = 100; - zLine = malloc( nLine ); - if( zLine==0 ) return 0; - n = 0; - while( 1 ){ - if( n+100>nLine ){ - nLine = nLine*2 + 100; - zLine = realloc(zLine, nLine); - if( zLine==0 ) return 0; - } - if( fgets(&zLine[n], nLine - n, in)==0 ){ - if( n==0 ){ - free(zLine); - return 0; - } - zLine[n] = 0; - break; - } - while( zLine[n] ){ - if( zLine[n]=='"' ) inQuote = !inQuote; - n++; - } - if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){ - n--; - if( n>0 && zLine[n-1]=='\r' ) n--; - zLine[n] = 0; - break; - } - } - zLine = realloc( zLine, n+1 ); - return zLine; +static char * +local_getline (char *zPrompt, FILE * in, int csvFlag) +{ + char *zLine; + int nLine; + int n; + int inQuote = 0; + + if (zPrompt && *zPrompt) + { + printf ("%s", zPrompt); + fflush (stdout); + } + nLine = 100; + zLine = malloc (nLine); + if (zLine == 0) + return 0; + n = 0; + while (1) + { + if (n + 100 > nLine) + { + nLine = nLine * 2 + 100; + zLine = realloc (zLine, nLine); + if (zLine == 0) + return 0; + } + if (fgets (&zLine[n], nLine - n, in) == 0) + { + if (n == 0) + { + free (zLine); + return 0; + } + zLine[n] = 0; + break; + } + while (zLine[n]) + { + if (zLine[n] == '"') + inQuote = !inQuote; + n++; + } + if (n > 0 && zLine[n - 1] == '\n' && (!inQuote || !csvFlag)) + { + n--; + if (n > 0 && zLine[n - 1] == '\r') + n--; + zLine[n] = 0; + break; + } + } + zLine = realloc (zLine, n + 1); + return zLine; } /* ** Retrieve a single line of input text. ** ** zPrior is a string of prior text retrieved. If not the empty ** string, then issue a continuation prompt. */ -static char *one_input_line(const char *zPrior, FILE *in){ - char *zPrompt; - char *zResult; - if( in!=0 ){ - return local_getline(0, in, 0); - } - if( zPrior && zPrior[0] ){ - zPrompt = continuePrompt; - }else{ - zPrompt = mainPrompt; - } - zResult = readline(zPrompt); +static char * +one_input_line (const char *zPrior, FILE * in) +{ + char *zPrompt; + char *zResult; + if (in != 0) + { + return local_getline (0, in, 0); + } + if (zPrior && zPrior[0]) + { + zPrompt = continuePrompt; + } + else + { + zPrompt = mainPrompt; + } + zResult = readline (zPrompt); #if defined(HAVE_READLINE) && HAVE_READLINE==1 - if( zResult && *zResult ) add_history(zResult); + if (zResult && *zResult) + add_history (zResult); #endif - return zResult; + return zResult; } -struct previous_mode_data { - int valid; /* Is there legit data in here? */ - int mode; - int showHeader; - int colWidth[100]; +struct previous_mode_data +{ + int valid; /* Is there legit data in here? */ + int mode; + int showHeader; + int colWidth[100]; }; /* ** An pointer to an instance of this structure is passed from ** the main program to the callback. This is used to communicate ** state and mode information. */ -struct callback_data { - sqlite3 *db; /* The database */ - int echoOn; /* True to echo input commands */ - int statsOn; /* True to display memory stats before each finalize */ - int cnt; /* Number of records displayed so far */ - FILE *out; /* Write results here */ - FILE *traceOut; /* Output for sqlite3_trace() */ - int nErr; /* Number of errors seen */ - int mode; /* An output mode setting */ - int writableSchema; /* True if PRAGMA writable_schema=ON */ - int showHeader; /* True to show column names in List or Column mode */ - char *zDestTable; /* Name of destination table when MODE_Insert */ - char separator[20]; /* Separator character for MODE_List */ - int colWidth[100]; /* Requested width of each column when in column mode*/ - int actualWidth[100]; /* Actual width of each column */ - char nullvalue[20]; /* The text to print when a NULL comes back from - ** the database */ - struct previous_mode_data explainPrev; - /* Holds the mode information just before - ** .explain ON */ - char outfile[FILENAME_MAX]; /* Filename for *out */ - const char *zDbFilename; /* name of the database file */ - const char *zVfs; /* Name of VFS to use */ - sqlite3_stmt *pStmt; /* Current statement if any. */ - FILE *pLog; /* Write log output here */ +struct callback_data +{ + sqlite3 *db; /* The database */ + int echoOn; /* True to echo input commands */ + int statsOn; /* True to display memory stats before each finalize */ + int cnt; /* Number of records displayed so far */ + FILE *out; /* Write results here */ + FILE *traceOut; /* Output for sqlite3_trace() */ + int nErr; /* Number of errors seen */ + int mode; /* An output mode setting */ + int writableSchema; /* True if PRAGMA writable_schema=ON */ + int showHeader; /* True to show column names in List or Column mode */ + char *zDestTable; /* Name of destination table when MODE_Insert */ + char separator[20]; /* Separator character for MODE_List */ + int colWidth[100]; /* Requested width of each column when in column mode */ + int actualWidth[100]; /* Actual width of each column */ + char nullvalue[20]; /* The text to print when a NULL comes back from + ** the database */ + struct previous_mode_data explainPrev; + /* Holds the mode information just before + ** .explain ON */ + char outfile[FILENAME_MAX]; /* Filename for *out */ + const char *zDbFilename; /* name of the database file */ + const char *zVfs; /* Name of VFS to use */ + sqlite3_stmt *pStmt; /* Current statement if any. */ + FILE *pLog; /* Write log output here */ }; /* ** These are the allowed modes. */ -#define MODE_Line 0 /* One column per line. Blank line between records */ -#define MODE_Column 1 /* One record per line in neat columns */ -#define MODE_List 2 /* One record per line with a separator */ -#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ -#define MODE_Html 4 /* Generate an XHTML table */ -#define MODE_Insert 5 /* Generate SQL "insert" statements */ -#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ -#define MODE_Csv 7 /* Quote strings, numbers are plain */ -#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ +#define MODE_Line 0 /* One column per line. Blank line between records */ +#define MODE_Column 1 /* One record per line in neat columns */ +#define MODE_List 2 /* One record per line with a separator */ +#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ +#define MODE_Html 4 /* Generate an XHTML table */ +#define MODE_Insert 5 /* Generate SQL "insert" statements */ +#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ +#define MODE_Csv 7 /* Quote strings, numbers are plain */ +#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ static const char *modeDescr[] = { - "line", - "column", - "list", - "semi", - "html", - "insert", - "tcl", - "csv", - "explain", + "line", + "column", + "list", + "semi", + "html", + "insert", + "tcl", + "csv", + "explain", }; /* ** Number of elements in an array */ @@ -994,443 +1071,578 @@ /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. */ -static int strlen30(const char *z){ - const char *z2 = z; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); +static int +strlen30 (const char *z) +{ + const char *z2 = z; + while (*z2) + { + z2++; + } + return 0x3fffffff & (int) (z2 - z); } /* ** A callback for the sqlite3_log() interface. */ -static void shellLog(void *pArg, int iErrCode, const char *zMsg){ - struct callback_data *p = (struct callback_data*)pArg; - if( p->pLog==0 ) return; - fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); - fflush(p->pLog); +static void +shellLog (void *pArg, int iErrCode, const char *zMsg) +{ + struct callback_data *p = (struct callback_data *) pArg; + if (p->pLog == 0) + return; + fprintf (p->pLog, "(%d) %s\n", iErrCode, zMsg); + fflush (p->pLog); } /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ -static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ - int i; - char *zBlob = (char *)pBlob; - fprintf(out,"X'"); - for(i=0; i0 ){ - fprintf(out,"%.*s",i,z); - } - if( z[i]=='<' ){ - fprintf(out,"<"); - }else if( z[i]=='&' ){ - fprintf(out,"&"); - }else if( z[i]=='>' ){ - fprintf(out,">"); - }else if( z[i]=='\"' ){ - fprintf(out,"""); - }else if( z[i]=='\'' ){ - fprintf(out,"'"); - }else{ - break; - } - z += i + 1; - } +static void +output_html_string (FILE * out, const char *z) +{ + int i; + while (*z) + { + for (i = 0; z[i] + && z[i] != '<' + && z[i] != '&' + && z[i] != '>' && z[i] != '\"' && z[i] != '\''; i++) + { + } + if (i > 0) + { + fprintf (out, "%.*s", i, z); + } + if (z[i] == '<') + { + fprintf (out, "<"); + } + else if (z[i] == '&') + { + fprintf (out, "&"); + } + else if (z[i] == '>') + { + fprintf (out, ">"); + } + else if (z[i] == '\"') + { + fprintf (out, """); + } + else if (z[i] == '\'') + { + fprintf (out, "'"); + } + else + { + break; + } + z += i + 1; + } } /* ** If a field contains any character identified by a 1 in the following ** array, then the string must be quoted for CSV. */ static const char needCsvQuote[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* ** Output a single term of CSV. Actually, p->separator is used for ** the separator, which may or may not be a comma. p->nullvalue is ** the null value. Strings are quoted if necessary. */ -static void output_csv(struct callback_data *p, const char *z, int bSep){ - FILE *out = p->out; - if( z==0 ){ - fprintf(out,"%s",p->nullvalue); - }else{ - int i; - int nSep = strlen30(p->separator); - for(i=0; z[i]; i++){ - if( needCsvQuote[((unsigned char*)z)[i]] - || (z[i]==p->separator[0] && - (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){ - i = 0; - break; - } - } - if( i==0 ){ - putc('"', out); - for(i=0; z[i]; i++){ - if( z[i]=='"' ) putc('"', out); - putc(z[i], out); - } - putc('"', out); - }else{ - fprintf(out, "%s", z); - } - } - if( bSep ){ - fprintf(p->out, "%s", p->separator); - } +static void +output_csv (struct callback_data *p, const char *z, int bSep) +{ + FILE *out = p->out; + if (z == 0) + { + fprintf (out, "%s", p->nullvalue); + } + else + { + int i; + int nSep = strlen30 (p->separator); + for (i = 0; z[i]; i++) + { + if (needCsvQuote[((unsigned char *) z)[i]] + || (z[i] == p->separator[0] && + (nSep == 1 || memcmp (z, p->separator, nSep) == 0))) + { + i = 0; + break; + } + } + if (i == 0) + { + putc ('"', out); + for (i = 0; z[i]; i++) + { + if (z[i] == '"') + putc ('"', out); + putc (z[i], out); + } + putc ('"', out); + } + else + { + fprintf (out, "%s", z); + } + } + if (bSep) + { + fprintf (p->out, "%s", p->separator); + } } #ifdef SIGINT /* ** This routine runs when the user presses Ctrl-C */ -static void interrupt_handler(int NotUsed){ - UNUSED_PARAMETER(NotUsed); - seenInterrupt = 1; - if( db ) sqlite3_interrupt(db); +static void +interrupt_handler (int NotUsed) +{ + UNUSED_PARAMETER (NotUsed); + seenInterrupt = 1; + if (db) + sqlite3_interrupt (db); } #endif /* ** This is the callback routine that the shell ** invokes for each row of a query result. */ -static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){ - int i; +static int +shell_callback (void *pArg, int nArg, char **azArg, char **azCol, int *aiType) +{ + int i; /* Sandro Furieri 11 July 2008 - supporting full UNICODE */ char *buf = NULL; int len; /* end Sandro Furieri 11 July 2008 */ - struct callback_data *p = (struct callback_data*)pArg; + struct callback_data *p = (struct callback_data *) pArg; - switch( p->mode ){ - case MODE_Line: { - int w = 5; - if( azArg==0 ) break; - for(i=0; iw ) w = len; - } - if( p->cnt++>0 ) fprintf(p->out,"\n"); - for(i=0; imode) + { + case MODE_Line: + { + int w = 5; + if (azArg == 0) + break; + for (i = 0; i < nArg; i++) + { + int len = strlen30 (azCol[i] ? azCol[i] : ""); + if (len > w) + w = len; + } + if (p->cnt++ > 0) + fprintf (p->out, "\n"); + for (i = 0; i < nArg; i++) + { /* Sandro Furieri 11 July 2008 fprintf(p->out,"%*s = %s\n", w, azCol[i], azArg[i] ? azArg[i] : p->nullvalue); */ - if (azArg[i] == 0) - fprintf (p->out, "%*s = %s\n", w, azCol[i], - p->nullvalue); - else - { - len = strlen (azArg[i]) + 1; - if (buf) - free (buf); - buf = malloc (len * 4); - strcpy (buf, azArg[i]); - convert_from_utf8 (buf, len * 4); - fprintf (p->out, "%*s = %s\n", w, azCol[i], - azArg[i] ? buf : p->nullvalue); - free(buf); - buf = NULL; - } + if (azArg[i] == 0) + fprintf (p->out, "%*s = %s\n", w, azCol[i], + p->nullvalue); + else + { + len = strlen (azArg[i]) + 1; + if (buf) + free (buf); + buf = malloc (len * 4); + strcpy (buf, azArg[i]); + convert_from_utf8 (buf, len * 4); + fprintf (p->out, "%*s = %s\n", w, azCol[i], + azArg[i] ? buf : p->nullvalue); + free (buf); + buf = NULL; + } /* end Sandro Furieri 11 July 2008 */ - } - break; - } - case MODE_Explain: - case MODE_Column: { - if( p->cnt++==0 ){ - for(i=0; icolWidth) ){ - w = p->colWidth[i]; - }else{ - w = 0; - } - if( w<=0 ){ - w = strlen30(azCol[i] ? azCol[i] : ""); - if( w<10 ) w = 10; - n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue); - if( wactualWidth) ){ - p->actualWidth[i] = w; - } - if( p->showHeader ){ - fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); - } - } - if( p->showHeader ){ - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - }else{ - w = 10; - } - fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" - "----------------------------------------------------------", - i==nArg-1 ? "\n": " "); - } - } - } - if( azArg==0 ) break; - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - }else{ - w = 10; - } - if( p->mode==MODE_Explain && azArg[i] && - strlen30(azArg[i])>w ){ - w = strlen30(azArg[i]); - } + } + break; + } + case MODE_Explain: + case MODE_Column: + { + if (p->cnt++ == 0) + { + for (i = 0; i < nArg; i++) + { + int w, n; + if (i < ArraySize (p->colWidth)) + { + w = p->colWidth[i]; + } + else + { + w = 0; + } + if (w <= 0) + { + w = strlen30 (azCol[i] ? azCol[i] : ""); + if (w < 10) + w = 10; + n = strlen30 (azArg + && azArg[i] ? azArg[i] : + p->nullvalue); + if (w < n) + w = n; + } + if (i < ArraySize (p->actualWidth)) + { + p->actualWidth[i] = w; + } + if (p->showHeader) + { + fprintf (p->out, "%-*.*s%s", w, w, azCol[i], + i == nArg - 1 ? "\n" : " "); + } + } + if (p->showHeader) + { + for (i = 0; i < nArg; i++) + { + int w; + if (i < ArraySize (p->actualWidth)) + { + w = p->actualWidth[i]; + } + else + { + w = 10; + } + fprintf (p->out, "%-*.*s%s", w, w, + "-----------------------------------" + "----------------------------------------------------------", + i == nArg - 1 ? "\n" : " "); + } + } + } + if (azArg == 0) + break; + for (i = 0; i < nArg; i++) + { + int w; + if (i < ArraySize (p->actualWidth)) + { + w = p->actualWidth[i]; + } + else + { + w = 10; + } + if (p->mode == MODE_Explain && azArg[i] && + strlen30 (azArg[i]) > w) + { + w = strlen30 (azArg[i]); + } /* Sandro Furieri 11 July 2008 fprintf(p->out,"%-*.*s%s",w,w, azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); */ - if (azArg[i] == 0) - fprintf (p->out, "%-*.*s%s", w, w, p->nullvalue, - i == nArg - 1 ? "\n" : " "); - else - { - len = strlen (azArg[i]) + 1; - if (buf) - free (buf); - buf = malloc (len * 4); - strcpy (buf, azArg[i]); - convert_from_utf8 (buf, len * 4); - fprintf (p->out, "%-*.*s%s", w, w, - azArg[i] ? buf : p->nullvalue, - i == nArg - 1 ? "\n" : " "); - free(buf); - buf = NULL; - } + if (azArg[i] == 0) + fprintf (p->out, "%-*.*s%s", w, w, p->nullvalue, + i == nArg - 1 ? "\n" : " "); + else + { + len = strlen (azArg[i]) + 1; + if (buf) + free (buf); + buf = malloc (len * 4); + strcpy (buf, azArg[i]); + convert_from_utf8 (buf, len * 4); + fprintf (p->out, "%-*.*s%s", w, w, + azArg[i] ? buf : p->nullvalue, + i == nArg - 1 ? "\n" : " "); + free (buf); + buf = NULL; + } /* end Sandro Furieri 11 July 2008 */ - fprintf(p->out,"%-*.*s%s",w,w, - azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); - } - break; - } - case MODE_Semi: - case MODE_List: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator); - } - } - if( azArg==0 ) break; - for(i=0; iout, "%-*.*s%s", w, w, + azArg[i] ? azArg[i] : p->nullvalue, + i == nArg - 1 ? "\n" : " "); + } + break; + } + case MODE_Semi: + case MODE_List: + { + if (p->cnt++ == 0 && p->showHeader) + { + for (i = 0; i < nArg; i++) + { + fprintf (p->out, "%s%s", azCol[i], + i == nArg - 1 ? "\n" : p->separator); + } + } + if (azArg == 0) + break; + for (i = 0; i < nArg; i++) + { /* Sandro Furieri 11 July 2008 char *z = azArg[i]; if( z==0 ) z = p->nullvalue; */ - char *z; - if (azArg[i] == 0) - z = p->nullvalue; - else - { - len = strlen (azArg[i]) + 1; - if (buf) - free (buf); - buf = malloc (len * 4); - z = buf; - strcpy (buf, azArg[i]); - convert_from_utf8 (buf, len * 4); - } + char *z; + if (azArg[i] == 0) + z = p->nullvalue; + else + { + len = strlen (azArg[i]) + 1; + if (buf) + free (buf); + buf = malloc (len * 4); + z = buf; + strcpy (buf, azArg[i]); + convert_from_utf8 (buf, len * 4); + } /* end Sandro Furieri 11 July 2008 */ - fprintf(p->out, "%s", z); - if (buf) - free(buf); - buf = NULL; - if( iout, "%s", p->separator); - }else if( p->mode==MODE_Semi ){ - fprintf(p->out, ";\n"); - }else{ - fprintf(p->out, "\n"); - } - } - break; - } - case MODE_Html: { - if( p->cnt++==0 && p->showHeader ){ - fprintf(p->out,""); - for(i=0; iout,""); - output_html_string(p->out, azCol[i]); - fprintf(p->out,"\n"); - } - fprintf(p->out,"\n"); - } - if( azArg==0 ) break; - fprintf(p->out,""); - for(i=0; iout,""); + fprintf (p->out, "%s", z); + if (buf) + free (buf); + buf = NULL; + if (i < nArg - 1) + { + fprintf (p->out, "%s", p->separator); + } + else if (p->mode == MODE_Semi) + { + fprintf (p->out, ";\n"); + } + else + { + fprintf (p->out, "\n"); + } + } + break; + } + case MODE_Html: + { + if (p->cnt++ == 0 && p->showHeader) + { + fprintf (p->out, ""); + for (i = 0; i < nArg; i++) + { + fprintf (p->out, ""); + output_html_string (p->out, azCol[i]); + fprintf (p->out, "\n"); + } + fprintf (p->out, "\n"); + } + if (azArg == 0) + break; + fprintf (p->out, ""); + for (i = 0; i < nArg; i++) + { + fprintf (p->out, ""); /* Sandro Furieri 11 July 2008 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); */ - if (azArg[i] == 0) - output_html_string (p->out, p->nullvalue); - else - { - len = strlen (azArg[i]) + 1; - if (buf) - free (buf); - buf = malloc (len * 4); - strcpy (buf, azArg[i]); - convert_from_utf8 (buf, len * 4); - output_html_string (p->out, - azArg[i] ? buf : p->nullvalue); - free(buf); - buf = NULL; - } + if (azArg[i] == 0) + output_html_string (p->out, p->nullvalue); + else + { + len = strlen (azArg[i]) + 1; + if (buf) + free (buf); + buf = malloc (len * 4); + strcpy (buf, azArg[i]); + convert_from_utf8 (buf, len * 4); + output_html_string (p->out, + azArg[i] ? buf : p->nullvalue); + free (buf); + buf = NULL; + } /* end Sandro Furieri 11 July 2008 */ - fprintf(p->out,"\n"); - } - fprintf(p->out,"\n"); - break; - } - case MODE_Tcl: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,azCol[i] ? azCol[i] : ""); - fprintf(p->out, "%s", p->separator); - } - fprintf(p->out,"\n"); - } - if( azArg==0 ) break; - for(i=0; iout, "\n"); + } + fprintf (p->out, "\n"); + break; + } + case MODE_Tcl: + { + if (p->cnt++ == 0 && p->showHeader) + { + for (i = 0; i < nArg; i++) + { + output_c_string (p->out, azCol[i] ? azCol[i] : ""); + fprintf (p->out, "%s", p->separator); + } + fprintf (p->out, "\n"); + } + if (azArg == 0) + break; + for (i = 0; i < nArg; i++) + { /* Sandro Furieri 11 July 2008 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); */ - if (azArg[i] == 0) - output_c_string (p->out, p->nullvalue); - else - { - len = strlen (azArg[i]) + 1; - if (buf) - free (buf); - buf = malloc (len * 4); - strcpy (buf, azArg[i]); - convert_from_utf8 (buf, len * 4); - output_c_string (p->out, - azArg[i] ? buf : p->nullvalue); - free(buf); - buf = NULL; - } + if (azArg[i] == 0) + output_c_string (p->out, p->nullvalue); + else + { + len = strlen (azArg[i]) + 1; + if (buf) + free (buf); + buf = malloc (len * 4); + strcpy (buf, azArg[i]); + convert_from_utf8 (buf, len * 4); + output_c_string (p->out, + azArg[i] ? buf : p->nullvalue); + free (buf); + buf = NULL; + } /* end Sandro Furieri 11 July 2008 */ - fprintf(p->out, "%s", p->separator); - } - fprintf(p->out,"\n"); - break; - } - case MODE_Csv: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,"\n"); - } - if( azArg==0 ) break; - for(i=0; iout, "%s", p->separator); + } + fprintf (p->out, "\n"); + break; + } + case MODE_Csv: + { + if (p->cnt++ == 0 && p->showHeader) + { + for (i = 0; i < nArg; i++) + { + output_csv (p, azCol[i] ? azCol[i] : "", + i < nArg - 1); + } + fprintf (p->out, "\n"); + } + if (azArg == 0) + break; + for (i = 0; i < nArg; i++) + { /* Sandro Furieri 11 July 2008 output_csv(p, azArg[i], iout,"\n"); - break; - } - case MODE_Insert: { - p->cnt++; - if( azArg==0 ) break; - fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable); - for(i=0; i0 ? ",": ""; - if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - fprintf(p->out,"%sNULL",zSep); - }else if( aiType && aiType[i]==SQLITE_TEXT ){ - if( zSep[0] ) fprintf(p->out,"%s",zSep); + } + fprintf (p->out, "\n"); + break; + } + case MODE_Insert: + { + p->cnt++; + if (azArg == 0) + break; + fprintf (p->out, "INSERT INTO %s VALUES(", p->zDestTable); + for (i = 0; i < nArg; i++) + { + char *zSep = i > 0 ? "," : ""; + if ((azArg[i] == 0) || (aiType && aiType[i] == SQLITE_NULL)) + { + fprintf (p->out, "%sNULL", zSep); + } + else if (aiType && aiType[i] == SQLITE_TEXT) + { + if (zSep[0]) + fprintf (p->out, "%s", zSep); /* Sandro Furieri 11 July 2008 output_quoted_string(p->out, azArg[i]); */ - if (azArg[i] == 0) - output_quoted_string (p->out, azArg[i]); - else - { - len = strlen (azArg[i]) + 1; - if (buf) - free (buf); - buf = malloc (len * 4); - strcpy (buf, azArg[i]); - convert_from_utf8 (buf, len * 4); - output_quoted_string (p->out, buf); - free(buf); - buf = NULL; - } + if (azArg[i] == 0) + output_quoted_string (p->out, azArg[i]); + else + { + len = strlen (azArg[i]) + 1; + if (buf) + free (buf); + buf = malloc (len * 4); + strcpy (buf, azArg[i]); + convert_from_utf8 (buf, len * 4); + output_quoted_string (p->out, buf); + free (buf); + buf = NULL; + } /* end Sandro Furieri 11 July 2008 */ - }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){ - fprintf(p->out,"%s%s",zSep, azArg[i]); - }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ - const void *pBlob = sqlite3_column_blob(p->pStmt, i); - int nBlob = sqlite3_column_bytes(p->pStmt, i); - if( zSep[0] ) fprintf(p->out,"%s",zSep); - output_hex_blob(p->out, pBlob, nBlob); - }else if( isNumber(azArg[i], 0) ){ - fprintf(p->out,"%s%s",zSep, azArg[i]); - }else{ - if( zSep[0] ) fprintf(p->out,"%s",zSep); - output_quoted_string(p->out, azArg[i]); - } - } - fprintf(p->out,");\n"); - break; - } - } - return 0; + } + else if (aiType + && (aiType[i] == SQLITE_INTEGER + || aiType[i] == SQLITE_FLOAT)) + { + fprintf (p->out, "%s%s", zSep, azArg[i]); + } + else if (aiType && aiType[i] == SQLITE_BLOB && p->pStmt) + { + const void *pBlob = sqlite3_column_blob (p->pStmt, i); + int nBlob = sqlite3_column_bytes (p->pStmt, i); + if (zSep[0]) + fprintf (p->out, "%s", zSep); + output_hex_blob (p->out, pBlob, nBlob); + } + else if (isNumber (azArg[i], 0)) + { + fprintf (p->out, "%s%s", zSep, azArg[i]); + } + else + { + if (zSep[0]) + fprintf (p->out, "%s", zSep); + output_quoted_string (p->out, azArg[i]); + } + } + fprintf (p->out, ");\n"); + break; + } + } + return 0; } /* ** This is the callback routine that the SQLite library ** invokes for each row of a query result. */ -static int callback(void *pArg, int nArg, char **azArg, char **azCol){ - /* since we don't have type info, call the shell_callback with a NULL value */ - return shell_callback(pArg, nArg, azArg, azCol, NULL); +static int +callback (void *pArg, int nArg, char **azArg, char **azCol) +{ + /* since we don't have type info, call the shell_callback with a NULL value */ + return shell_callback (pArg, nArg, azArg, azCol, NULL); } /* ** Set the destination table field of the callback_data structure to ** the name of the table given. Escape any quote characters in the ** table name. */ -static void set_table_name(struct callback_data *p, const char *zName){ - int i, n; - int needQuote; - char *z; - - if( p->zDestTable ){ - free(p->zDestTable); - p->zDestTable = 0; - } - if( zName==0 ) return; - needQuote = !isalpha((unsigned char)*zName) && *zName!='_'; - for(i=n=0; zName[i]; i++, n++){ - if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){ - needQuote = 1; - if( zName[i]=='\'' ) n++; - } - } - if( needQuote ) n += 2; - z = p->zDestTable = malloc( n+1 ); - if( z==0 ){ - fprintf(stderr,"Error: out of memory\n"); - exit(1); - } - n = 0; - if( needQuote ) z[n++] = '\''; - for(i=0; zName[i]; i++){ - z[n++] = zName[i]; - if( zName[i]=='\'' ) z[n++] = '\''; - } - if( needQuote ) z[n++] = '\''; - z[n] = 0; +static void +set_table_name (struct callback_data *p, const char *zName) +{ + int i, n; + int needQuote; + char *z; + + if (p->zDestTable) + { + free (p->zDestTable); + p->zDestTable = 0; + } + if (zName == 0) + return; + needQuote = !isalpha ((unsigned char) *zName) && *zName != '_'; + for (i = n = 0; zName[i]; i++, n++) + { + if (!isalnum ((unsigned char) zName[i]) && zName[i] != '_') + { + needQuote = 1; + if (zName[i] == '\'') + n++; + } + } + if (needQuote) + n += 2; + z = p->zDestTable = malloc (n + 1); + if (z == 0) + { + fprintf (stderr, "Error: out of memory\n"); + exit (1); + } + n = 0; + if (needQuote) + z[n++] = '\''; + for (i = 0; zName[i]; i++) + { + z[n++] = zName[i]; + if (zName[i] == '\'') + z[n++] = '\''; + } + if (needQuote) + z[n++] = '\''; + z[n] = 0; } /* zIn is either a pointer to a NULL-terminated string in memory obtained ** from malloc(), or a NULL pointer. The string pointed to by zAppend is ** added to zIn, and the result returned in memory obtained from malloc(). @@ -1553,45 +1799,56 @@ ** zIn, if it was not NULL, is freed. ** ** If the third argument, quote, is not '\0', then it is used as a ** quote character for zAppend. */ -static char *appendText(char *zIn, char const *zAppend, char quote){ - int len; - int i; - int nAppend = strlen30(zAppend); - int nIn = (zIn?strlen30(zIn):0); - - len = nAppend+nIn+1; - if( quote ){ - len += 2; - for(i=0; idb, zSelect, -1, &pSelect, 0); - if( rc!=SQLITE_OK || !pSelect ){ - fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); - p->nErr++; - return rc; - } - rc = sqlite3_step(pSelect); - nResult = sqlite3_column_count(pSelect); - while( rc==SQLITE_ROW ){ - if( zFirstRow ){ - fprintf(p->out, "%s", zFirstRow); - zFirstRow = 0; - } - z = (const char*)sqlite3_column_text(pSelect, 0); - fprintf(p->out, "%s", z); - for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); - } - if( z==0 ) z = ""; - while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; - if( z[0] ){ - fprintf(p->out, "\n;\n"); - }else{ - fprintf(p->out, ";\n"); - } - rc = sqlite3_step(pSelect); - } - rc = sqlite3_finalize(pSelect); - if( rc!=SQLITE_OK ){ - fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); - p->nErr++; - } - return rc; +static int +run_table_dump_query (struct callback_data *p, /* Query context */ + const char *zSelect, /* SELECT statement to extract content */ + const char *zFirstRow /* Print before first row, if not NULL */ + ) +{ + sqlite3_stmt *pSelect; + int rc; + int nResult; + int i; + const char *z; + rc = sqlite3_prepare (p->db, zSelect, -1, &pSelect, 0); + if (rc != SQLITE_OK || !pSelect) + { + fprintf (p->out, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg (p->db)); + p->nErr++; + return rc; + } + rc = sqlite3_step (pSelect); + nResult = sqlite3_column_count (pSelect); + while (rc == SQLITE_ROW) + { + if (zFirstRow) + { + fprintf (p->out, "%s", zFirstRow); + zFirstRow = 0; + } + z = (const char *) sqlite3_column_text (pSelect, 0); + fprintf (p->out, "%s", z); + for (i = 1; i < nResult; i++) + { + fprintf (p->out, ",%s", sqlite3_column_text (pSelect, i)); + } + if (z == 0) + z = ""; + while (z[0] && (z[0] != '-' || z[1] != '-')) + z++; + if (z[0]) + { + fprintf (p->out, "\n;\n"); + } + else + { + fprintf (p->out, ";\n"); + } + rc = sqlite3_step (pSelect); + } + rc = sqlite3_finalize (pSelect); + if (rc != SQLITE_OK) + { + fprintf (p->out, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg (p->db)); + p->nErr++; + } + return rc; } /* ** Allocate space and save off current error string. */ -static char *save_err_msg( - sqlite3 *db /* Database to query */ -){ - int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); - char *zErrMsg = sqlite3_malloc(nErrMsg); - if( zErrMsg ){ - memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); - } - return zErrMsg; +static char * +save_err_msg (sqlite3 * db /* Database to query */ + ) +{ + int nErrMsg = 1 + strlen30 (sqlite3_errmsg (db)); + char *zErrMsg = sqlite3_malloc (nErrMsg); + if (zErrMsg) + { + memcpy (zErrMsg, sqlite3_errmsg (db), nErrMsg); + } + return zErrMsg; } /* ** Display memory stats. */ -static int display_stats( - sqlite3 *db, /* Database to query */ - struct callback_data *pArg, /* Pointer to struct callback_data */ - int bReset /* True to reset the stats */ -){ - int iCur; - int iHiwtr; +static int +display_stats (sqlite3 * db, /* Database to query */ + struct callback_data *pArg, /* Pointer to struct callback_data */ + int bReset /* True to reset the stats */ + ) +{ + int iCur; + int iHiwtr; - if( pArg && pArg->out ){ - - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr); + if (pArg && pArg->out) + { + + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); + fprintf (pArg->out, + "Memory Used: %d (max %d) bytes\n", + iCur, iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset); + fprintf (pArg->out, + "Number of Outstanding Allocations: %d (max %d)\n", iCur, + iHiwtr); /* ** Not currently used by the CLI. ** iHiwtr = iCur = -1; ** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset); ** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr); */ - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, + "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", + iCur, iHiwtr); /* ** Not currently used by the CLI. ** iHiwtr = iCur = -1; ** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); ** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr); */ - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, + "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", + iCur, iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); + fprintf (pArg->out, "Largest Allocation: %d bytes\n", + iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); + fprintf (pArg->out, "Largest Pcache Allocation: %d bytes\n", + iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); + fprintf (pArg->out, "Largest Scratch Allocation: %d bytes\n", + iHiwtr); #ifdef YYTRACKMAXSTACKDEPTH - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr); + iHiwtr = iCur = -1; + sqlite3_status (SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset); + fprintf (pArg->out, + "Deepest Parser Stack: %d (max %d)\n", iCur, + iHiwtr); #endif - } + } /* Sandro Furieri 1 November 2012 - depending on SQLite version */ - if( pArg && pArg->out && db ){ - iHiwtr = iCur = -1; + if (pArg && pArg->out && db) + { + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_USED - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); + sqlite3_db_status (db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, + "Lookaside Slots Used: %d (max %d)\n", iCur, + iHiwtr); #else - fprintf(pArg->out, "Lookaside Slots Used: n.a.\n"); + fprintf (pArg->out, "Lookaside Slots Used: n.a.\n"); #endif #ifdef HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_HIT - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr); + sqlite3_db_status (db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, "Successful lookaside attempts: %d\n", + iHiwtr); #else - fprintf(pArg->out, "Successful lookaside attempts: n.a.\n"); + fprintf (pArg->out, "Successful lookaside attempts: n.a.\n"); #endif #ifdef HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr); + sqlite3_db_status (db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, + &iHiwtr, bReset); + fprintf (pArg->out, "Lookaside failures due to size: %d\n", + iHiwtr); #else - fprintf(pArg->out, "Lookaside failures due to size: n.a.\n"); + fprintf (pArg->out, "Lookaside failures due to size: n.a.\n"); #endif #ifdef HAVE_DECL_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr); + sqlite3_db_status (db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, + &iHiwtr, bReset); + fprintf (pArg->out, "Lookaside failures due to OOM: %d\n", + iHiwtr); #else - fprintf(pArg->out, "Lookaside failures due to OOM: n.a.\n"); + fprintf (pArg->out, "Lookaside failures due to OOM: n.a.\n"); #endif - iHiwtr = iCur = -1; + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_CACHE_USED - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); + sqlite3_db_status (db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, "Pager Heap Usage: %d bytes\n", + iCur); #else - fprintf(pArg->out, "Pager Heap Usage: n.a.\n"); -#endif - iHiwtr = iCur = -1; + fprintf (pArg->out, "Pager Heap Usage: n.a.\n"); +#endif + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_CACHE_HIT - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); - fprintf(pArg->out, "Page cache hits: %d\n", iCur); + sqlite3_db_status (db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); + fprintf (pArg->out, "Page cache hits: %d\n", + iCur); #else - fprintf(pArg->out, "Page cache hits: n.a.\n"); + fprintf (pArg->out, "Page cache hits: n.a.\n"); #endif - iHiwtr = iCur = -1; + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_CACHE_MISS - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - fprintf(pArg->out, "Page cache misses: %d\n", iCur); + sqlite3_db_status (db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); + fprintf (pArg->out, "Page cache misses: %d\n", + iCur); #else - fprintf(pArg->out, "Page cache misses: n.a.\n"); + fprintf (pArg->out, "Page cache misses: n.a.\n"); #endif - iHiwtr = iCur = -1; + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_CACHE_WRITE - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - fprintf(pArg->out, "Page cache writes: %d\n", iCur); + sqlite3_db_status (db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, + 1); + fprintf (pArg->out, "Page cache writes: %d\n", + iCur); #else - fprintf(pArg->out, "Page cache writes: n.a.\n"); + fprintf (pArg->out, "Page cache writes: n.a.\n"); #endif - iHiwtr = iCur = -1; + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_SCHEMA_USED - sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur); + sqlite3_db_status (db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, "Schema Heap Usage: %d bytes\n", + iCur); #else - fprintf(pArg->out, "Schema Heap Usage: n.a.\n"); -#endif - iHiwtr = iCur = -1; + fprintf (pArg->out, "Schema Heap Usage: n.a.\n"); +#endif + iHiwtr = iCur = -1; #ifdef HAVE_DECL_SQLITE_DBSTATUS_STMT_USED - sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur); + sqlite3_db_status (db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, + bReset); + fprintf (pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", + iCur); #else - fprintf(pArg->out, "Statement Heap/Lookaside Usage: n.a.\n"); + fprintf (pArg->out, "Statement Heap/Lookaside Usage: n.a.\n"); #endif - } + } - if( pArg && pArg->out && db && pArg->pStmt ){ + if (pArg && pArg->out && db && pArg->pStmt) + { #ifdef HAVE_DECL_SQLITE_STMTSTATUS_FULLSCAN_STEP - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); - fprintf(pArg->out, "Fullscan Steps: %d\n", iCur); + iCur = + sqlite3_stmt_status (pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, + bReset); + fprintf (pArg->out, "Fullscan Steps: %d\n", + iCur); #else - fprintf(pArg->out, "Fullscan Steps: n.a.\n"); + fprintf (pArg->out, "Fullscan Steps: n.a.\n"); #endif #ifdef HAVE_DECL_SQLITE_STMTSTATUS_SORT - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); - fprintf(pArg->out, "Sort Operations: %d\n", iCur); + iCur = + sqlite3_stmt_status (pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); + fprintf (pArg->out, "Sort Operations: %d\n", + iCur); #else - fprintf(pArg->out, "Sort Operations: n.a.\n"); + fprintf (pArg->out, "Sort Operations: n.a.\n"); #endif #ifdef HAVE_DECL_SQLITE_STMTSTATUS_AUTOINDEX - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset); - fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur); + iCur = + sqlite3_stmt_status (pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, + bReset); + fprintf (pArg->out, "Autoindex Inserts: %d\n", + iCur); #else - fprintf(pArg->out, "Autoindex Inserts: n.a.\n"); + fprintf (pArg->out, "Autoindex Inserts: n.a.\n"); #endif - } + } /* end sandro 1 November 2012 */ - return 0; + return 0; } /* ** Execute a statement or set of statements. Print ** any result rows/columns depending on the current mode @@ -1818,247 +2136,322 @@ ** ** This is very similar to SQLite's built-in sqlite3_exec() ** function except it takes a slightly different callback ** and callback data argument. */ -static int shell_exec( - sqlite3 *db, /* An open database */ - const char *zSql, /* SQL to be evaluated */ - int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ - /* (not the same as sqlite3_exec) */ - struct callback_data *pArg, /* Pointer to struct callback_data */ - char **pzErrMsg /* Error msg written here */ -){ - sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ - int rc = SQLITE_OK; /* Return Code */ - int rc2; - const char *zLeftover; /* Tail of unprocessed SQL */ - - if( pzErrMsg ){ - *pzErrMsg = NULL; - } - - while( zSql[0] && (SQLITE_OK == rc) ){ - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); - if( SQLITE_OK != rc ){ - if( pzErrMsg ){ - *pzErrMsg = save_err_msg(db); - } - }else{ - if( !pStmt ){ - /* this happens for a comment or white-space */ - zSql = zLeftover; - while( IsSpace(zSql[0]) ) zSql++; - continue; - } - - /* save off the prepared statment handle and reset row count */ - if( pArg ){ - pArg->pStmt = pStmt; - pArg->cnt = 0; - } - - /* echo the sql statement if echo on */ - if( pArg && pArg->echoOn ){ - const char *zStmtSql = sqlite3_sql(pStmt); - fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); - } - - /* Output TESTCTRL_EXPLAIN text of requested */ - if( pArg && pArg->mode==MODE_Explain ){ +static int +shell_exec (sqlite3 * db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + int (*xCallback) (void *, int, char **, char **, int *), /* Callback function */ + /* (not the same as sqlite3_exec) */ + struct callback_data *pArg, /* Pointer to struct callback_data */ + char **pzErrMsg /* Error msg written here */ + ) +{ + sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ + int rc = SQLITE_OK; /* Return Code */ + int rc2; + const char *zLeftover; /* Tail of unprocessed SQL */ + + if (pzErrMsg) + { + *pzErrMsg = NULL; + } + + while (zSql[0] && (SQLITE_OK == rc)) + { + rc = sqlite3_prepare_v2 (db, zSql, -1, &pStmt, &zLeftover); + if (SQLITE_OK != rc) + { + if (pzErrMsg) + { + *pzErrMsg = save_err_msg (db); + } + } + else + { + if (!pStmt) + { + /* this happens for a comment or white-space */ + zSql = zLeftover; + while (IsSpace (zSql[0])) + zSql++; + continue; + } + + /* save off the prepared statment handle and reset row count */ + if (pArg) + { + pArg->pStmt = pStmt; + pArg->cnt = 0; + } + + /* echo the sql statement if echo on */ + if (pArg && pArg->echoOn) + { + const char *zStmtSql = sqlite3_sql (pStmt); + fprintf (pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); + } + + /* Output TESTCTRL_EXPLAIN text of requested */ + if (pArg && pArg->mode == MODE_Explain) + { /* Sandro Furieri 1 November 2012 - depending on SQLite version */ #ifdef HAVE_DECL_SQLITE_TESTCTRL_EXPLAIN_STMT - const char *zExplain = 0; - sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); - if( zExplain && zExplain[0] ){ - fprintf(pArg->out, "%s", zExplain); - } + const char *zExplain = 0; + sqlite3_test_control (SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, + &zExplain); + if (zExplain && zExplain[0]) + { + fprintf (pArg->out, "%s", zExplain); + } #else - fprintf(pArg->out, "TESTCTRL_EXPLAIN: unsupported"); + fprintf (pArg->out, "TESTCTRL_EXPLAIN: unsupported"); #endif /* end sandro 1 November 2012 */ - } - - /* perform the first step. this will tell us if we - ** have a result set or not and how wide it is. - */ - rc = sqlite3_step(pStmt); - /* if we have a result set... */ - if( SQLITE_ROW == rc ){ - /* if we have a callback... */ - if( xCallback ){ - /* allocate space for col name ptr, value ptr, and type */ - int nCol = sqlite3_column_count(pStmt); - void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1); - if( !pData ){ - rc = SQLITE_NOMEM; - }else{ - char **azCols = (char **)pData; /* Names of result columns */ - char **azVals = &azCols[nCol]; /* Results */ - int *aiTypes = (int *)&azVals[nCol]; /* Result types */ - int i; - assert(sizeof(int) <= sizeof(char *)); - /* save off ptrs to column names */ - for(i=0; istatsOn ){ - display_stats(db, pArg, 0); - } - - /* Finalize the statement just executed. If this fails, save a - ** copy of the error message. Otherwise, set zSql to point to the - ** next statement to execute. */ - rc2 = sqlite3_finalize(pStmt); - if( rc!=SQLITE_NOMEM ) rc = rc2; - if( rc==SQLITE_OK ){ - zSql = zLeftover; - while( IsSpace(zSql[0]) ) zSql++; - }else if( pzErrMsg ){ - *pzErrMsg = save_err_msg(db); - } - - /* clear saved stmt handle */ - if( pArg ){ - pArg->pStmt = NULL; - } - } - } /* end while */ - - return rc; + } + + /* perform the first step. this will tell us if we + ** have a result set or not and how wide it is. + */ + rc = sqlite3_step (pStmt); + /* if we have a result set... */ + if (SQLITE_ROW == rc) + { + /* if we have a callback... */ + if (xCallback) + { + /* allocate space for col name ptr, value ptr, and type */ + int nCol = sqlite3_column_count (pStmt); + void *pData = + sqlite3_malloc (3 * nCol * + sizeof (const char *) + 1); + if (!pData) + { + rc = SQLITE_NOMEM; + } + else + { + char **azCols = (char **) pData; /* Names of result columns */ + char **azVals = &azCols[nCol]; /* Results */ + int *aiTypes = (int *) &azVals[nCol]; /* Result types */ + int i; + assert (sizeof (int) <= sizeof (char *)); + /* save off ptrs to column names */ + for (i = 0; i < nCol; i++) + { + azCols[i] = + (char *) sqlite3_column_name (pStmt, + i); + } + do + { + /* extract the data and data types */ + for (i = 0; i < nCol; i++) + { + azVals[i] = + (char *) + sqlite3_column_text (pStmt, + i); + aiTypes[i] = + sqlite3_column_type (pStmt, + i); + if (!azVals[i] + && (aiTypes[i] != + SQLITE_NULL)) + { + rc = SQLITE_NOMEM; + break; /* from for */ + } + } /* end for */ + + /* if data and types extracted successfully... */ + if (SQLITE_ROW == rc) + { + /* call the supplied callback with the result row data */ + if (xCallback + (pArg, nCol, azVals, azCols, + aiTypes)) + { + rc = SQLITE_ABORT; + } + else + { + rc = sqlite3_step (pStmt); + } + } + } + while (SQLITE_ROW == rc); + sqlite3_free (pData); + } + } + else + { + do + { + rc = sqlite3_step (pStmt); + } + while (rc == SQLITE_ROW); + } + } + + /* print usage stats if stats on */ + if (pArg && pArg->statsOn) + { + display_stats (db, pArg, 0); + } + + /* Finalize the statement just executed. If this fails, save a + ** copy of the error message. Otherwise, set zSql to point to the + ** next statement to execute. */ + rc2 = sqlite3_finalize (pStmt); + if (rc != SQLITE_NOMEM) + rc = rc2; + if (rc == SQLITE_OK) + { + zSql = zLeftover; + while (IsSpace (zSql[0])) + zSql++; + } + else if (pzErrMsg) + { + *pzErrMsg = save_err_msg (db); + } + + /* clear saved stmt handle */ + if (pArg) + { + pArg->pStmt = NULL; + } + } + } /* end while */ + + return rc; } /* ** This is a different callback routine used for dumping the database. ** Each row received by this callback consists of a table name, ** the table type ("index" or "table") and SQL to create the table. ** This routine should print text sufficient to recreate the table. */ -static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ - int rc; - const char *zTable; - const char *zType; - const char *zSql; - const char *zPrepStmt = 0; - struct callback_data *p = (struct callback_data *)pArg; - - UNUSED_PARAMETER(azCol); - if( nArg!=3 ) return 1; - zTable = azArg[0]; - zType = azArg[1]; - zSql = azArg[2]; - - if( strcmp(zTable, "sqlite_sequence")==0 ){ - zPrepStmt = "DELETE FROM sqlite_sequence;\n"; - }else if( strcmp(zTable, "sqlite_stat1")==0 ){ - fprintf(p->out, "ANALYZE sqlite_master;\n"); - }else if( strncmp(zTable, "sqlite_", 7)==0 ){ - return 0; - }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ - char *zIns; - if( !p->writableSchema ){ - fprintf(p->out, "PRAGMA writable_schema=ON;\n"); - p->writableSchema = 1; - } - zIns = sqlite3_mprintf( - "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" - "VALUES('table','%q','%q',0,'%q');", - zTable, zTable, zSql); - fprintf(p->out, "%s\n", zIns); - sqlite3_free(zIns); - return 0; - }else{ - fprintf(p->out, "%s;\n", zSql); - } - - if( strcmp(zType, "table")==0 ){ - sqlite3_stmt *pTableInfo = 0; - char *zSelect = 0; - char *zTableInfo = 0; - char *zTmp = 0; - int nRow = 0; - - zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); - zTableInfo = appendText(zTableInfo, zTable, '"'); - zTableInfo = appendText(zTableInfo, ");", 0); - - rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0); - free(zTableInfo); - if( rc!=SQLITE_OK || !pTableInfo ){ - return 1; - } - - zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); - /* Always quote the table name, even if it appears to be pure ascii, - ** in case it is a keyword. Ex: INSERT INTO "table" ... */ - zTmp = appendText(zTmp, zTable, '"'); - if( zTmp ){ - zSelect = appendText(zSelect, zTmp, '\''); - free(zTmp); - } - zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); - rc = sqlite3_step(pTableInfo); - while( rc==SQLITE_ROW ){ - const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1); - zSelect = appendText(zSelect, "quote(", 0); - zSelect = appendText(zSelect, zText, '"'); - rc = sqlite3_step(pTableInfo); - if( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, "), ", 0); - }else{ - zSelect = appendText(zSelect, ") ", 0); - } - nRow++; - } - rc = sqlite3_finalize(pTableInfo); - if( rc!=SQLITE_OK || nRow==0 ){ - free(zSelect); - return 1; - } - zSelect = appendText(zSelect, "|| ')' FROM ", 0); - zSelect = appendText(zSelect, zTable, '"'); - - rc = run_table_dump_query(p, zSelect, zPrepStmt); - if( rc==SQLITE_CORRUPT ){ - zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); - run_table_dump_query(p, zSelect, 0); - } - free(zSelect); - } - return 0; +static int +dump_callback (void *pArg, int nArg, char **azArg, char **azCol) +{ + int rc; + const char *zTable; + const char *zType; + const char *zSql; + const char *zPrepStmt = 0; + struct callback_data *p = (struct callback_data *) pArg; + + UNUSED_PARAMETER (azCol); + if (nArg != 3) + return 1; + zTable = azArg[0]; + zType = azArg[1]; + zSql = azArg[2]; + + if (strcmp (zTable, "sqlite_sequence") == 0) + { + zPrepStmt = "DELETE FROM sqlite_sequence;\n"; + } + else if (strcmp (zTable, "sqlite_stat1") == 0) + { + fprintf (p->out, "ANALYZE sqlite_master;\n"); + } + else if (strncmp (zTable, "sqlite_", 7) == 0) + { + return 0; + } + else if (strncmp (zSql, "CREATE VIRTUAL TABLE", 20) == 0) + { + char *zIns; + if (!p->writableSchema) + { + fprintf (p->out, "PRAGMA writable_schema=ON;\n"); + p->writableSchema = 1; + } + zIns = + sqlite3_mprintf + ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','%q','%q',0,'%q');", zTable, zTable, zSql); + fprintf (p->out, "%s\n", zIns); + sqlite3_free (zIns); + return 0; + } + else + { + fprintf (p->out, "%s;\n", zSql); + } + + if (strcmp (zType, "table") == 0) + { + sqlite3_stmt *pTableInfo = 0; + char *zSelect = 0; + char *zTableInfo = 0; + char *zTmp = 0; + int nRow = 0; + + zTableInfo = appendText (zTableInfo, "PRAGMA table_info(", 0); + zTableInfo = appendText (zTableInfo, zTable, '"'); + zTableInfo = appendText (zTableInfo, ");", 0); + + rc = sqlite3_prepare (p->db, zTableInfo, -1, &pTableInfo, 0); + free (zTableInfo); + if (rc != SQLITE_OK || !pTableInfo) + { + return 1; + } + + zSelect = appendText (zSelect, "SELECT 'INSERT INTO ' || ", 0); + /* Always quote the table name, even if it appears to be pure ascii, + ** in case it is a keyword. Ex: INSERT INTO "table" ... */ + zTmp = appendText (zTmp, zTable, '"'); + if (zTmp) + { + zSelect = appendText (zSelect, zTmp, '\''); + free (zTmp); + } + zSelect = appendText (zSelect, " || ' VALUES(' || ", 0); + rc = sqlite3_step (pTableInfo); + while (rc == SQLITE_ROW) + { + const char *zText = + (const char *) sqlite3_column_text (pTableInfo, 1); + zSelect = appendText (zSelect, "quote(", 0); + zSelect = appendText (zSelect, zText, '"'); + rc = sqlite3_step (pTableInfo); + if (rc == SQLITE_ROW) + { + zSelect = appendText (zSelect, "), ", 0); + } + else + { + zSelect = appendText (zSelect, ") ", 0); + } + nRow++; + } + rc = sqlite3_finalize (pTableInfo); + if (rc != SQLITE_OK || nRow == 0) + { + free (zSelect); + return 1; + } + zSelect = appendText (zSelect, "|| ')' FROM ", 0); + zSelect = appendText (zSelect, zTable, '"'); + + rc = run_table_dump_query (p, zSelect, zPrepStmt); + if (rc == SQLITE_CORRUPT) + { + zSelect = appendText (zSelect, " ORDER BY rowid DESC", 0); + run_table_dump_query (p, zSelect, 0); + } + free (zSelect); + } + return 0; } static void spatialite_autocreate (sqlite3 * db) { @@ -2088,15 +2481,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } spatial_ref_sys_init (db, 1); } @@ -2106,103 +2499,107 @@ ** the contents of the query are output as SQL statements. ** ** If we get a SQLITE_CORRUPT error, rerun the query after appending ** "ORDER BY rowid DESC" to the end. */ -static int run_schema_dump_query( - struct callback_data *p, - const char *zQuery -){ - int rc; - char *zErr = 0; - rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); - if( rc==SQLITE_CORRUPT ){ - char *zQ2; - int len = strlen30(zQuery); - fprintf(p->out, "/****** CORRUPTION ERROR *******/\n"); - if( zErr ){ - fprintf(p->out, "/****** %s ******/\n", zErr); - sqlite3_free(zErr); - zErr = 0; - } - zQ2 = malloc( len+100 ); - if( zQ2==0 ) return rc; - sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); - rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); - if( rc ){ - fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); - }else{ - rc = SQLITE_CORRUPT; - } - sqlite3_free(zErr); - free(zQ2); - } - return rc; +static int +run_schema_dump_query (struct callback_data *p, const char *zQuery) +{ + int rc; + char *zErr = 0; + rc = sqlite3_exec (p->db, zQuery, dump_callback, p, &zErr); + if (rc == SQLITE_CORRUPT) + { + char *zQ2; + int len = strlen30 (zQuery); + fprintf (p->out, "/****** CORRUPTION ERROR *******/\n"); + if (zErr) + { + fprintf (p->out, "/****** %s ******/\n", zErr); + sqlite3_free (zErr); + zErr = 0; + } + zQ2 = malloc (len + 100); + if (zQ2 == 0) + return rc; + sqlite3_snprintf (len + 100, zQ2, "%s ORDER BY rowid DESC", zQuery); + rc = sqlite3_exec (p->db, zQ2, dump_callback, p, &zErr); + if (rc) + { + fprintf (p->out, "/****** ERROR: %s ******/\n", zErr); + } + else + { + rc = SQLITE_CORRUPT; + } + sqlite3_free (zErr); + free (zQ2); + } + return rc; } /* ** Text of a help message */ static char zHelp[] = - ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" - ".bail ON|OFF Stop after hitting an error. Default OFF\n" - ".databases List names and files of attached databases\n" - ".dump ?TABLE? ... Dump the database in an SQL text format\n" - " If TABLE specified, only dump tables matching\n" - " LIKE pattern TABLE.\n" - ".echo ON|OFF Turn command echo on or off\n" - ".exit Exit this program\n" - ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n" - " With no args, it turns EXPLAIN on.\n" - ".header(s) ON|OFF Turn display of headers on or off\n" - ".help Show this message\n" - ".import FILE TABLE Import data from FILE into TABLE\n" - ".indices ?TABLE? Show names of all indices\n" - " If TABLE specified, only show indices for tables\n" - " matching LIKE pattern TABLE.\n" + ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" + ".bail ON|OFF Stop after hitting an error. Default OFF\n" + ".databases List names and files of attached databases\n" + ".dump ?TABLE? ... Dump the database in an SQL text format\n" + " If TABLE specified, only dump tables matching\n" + " LIKE pattern TABLE.\n" + ".echo ON|OFF Turn command echo on or off\n" + ".exit Exit this program\n" + ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n" + " With no args, it turns EXPLAIN on.\n" + ".header(s) ON|OFF Turn display of headers on or off\n" + ".help Show this message\n" + ".import FILE TABLE Import data from FILE into TABLE\n" + ".indices ?TABLE? Show names of all indices\n" + " If TABLE specified, only show indices for tables\n" + " matching LIKE pattern TABLE.\n" #ifdef SQLITE_ENABLE_IOTRACE - ".iotrace FILE Enable I/O diagnostic logging to FILE\n" + ".iotrace FILE Enable I/O diagnostic logging to FILE\n" #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION - ".load FILE ?ENTRY? Load an extension library\n" -#endif - ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" - ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" - " csv Comma-separated values\n" - " column Left-aligned columns. (See .width)\n" - " html HTML code\n" - " insert SQL insert statements for TABLE\n" - " line One value per line\n" - " list Values delimited by .separator string\n" - " tabs Tab-separated values\n" - " tcl TCL list elements\n" - ".nullvalue STRING Print STRING in place of NULL values\n" - ".output FILENAME Send output to FILENAME\n" - ".output stdout Send output to the screen\n" - ".prompt MAIN CONTINUE Replace the standard prompts\n" - ".quit Exit this program\n" - ".read FILENAME Execute SQL in FILENAME\n" - ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" - ".schema ?TABLE? Show the CREATE statements\n" - " If TABLE specified, only show tables matching\n" - " LIKE pattern TABLE.\n" - ".separator STRING Change separator used by output mode and .import\n" - ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" - ".show Show the current values for various settings\n" - ".stats ON|OFF Turn stats on or off\n" - ".system CMD ARGS... Run CMD ARGS... in a system shell\n" - ".tables ?TABLE? List names of tables\n" - " If TABLE specified, only list tables matching\n" - " LIKE pattern TABLE.\n" - ".timeout MS Try opening locked tables for MS milliseconds\n" - ".trace FILE|off Output each SQL statement as it is run\n" - ".vfsname ?AUX? Print the name of the VFS stack\n" - ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" -; + ".load FILE ?ENTRY? Load an extension library\n" +#endif + ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" + ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" + " csv Comma-separated values\n" + " column Left-aligned columns. (See .width)\n" + " html HTML
code\n" + " insert SQL insert statements for TABLE\n" + " line One value per line\n" + " list Values delimited by .separator string\n" + " tabs Tab-separated values\n" + " tcl TCL list elements\n" + ".nullvalue STRING Print STRING in place of NULL values\n" + ".output FILENAME Send output to FILENAME\n" + ".output stdout Send output to the screen\n" + ".prompt MAIN CONTINUE Replace the standard prompts\n" + ".quit Exit this program\n" + ".read FILENAME Execute SQL in FILENAME\n" + ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" + ".schema ?TABLE? Show the CREATE statements\n" + " If TABLE specified, only show tables matching\n" + " LIKE pattern TABLE.\n" + ".separator STRING Change separator used by output mode and .import\n" + ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" + ".show Show the current values for various settings\n" + ".stats ON|OFF Turn stats on or off\n" + ".system CMD ARGS... Run CMD ARGS... in a system shell\n" + ".tables ?TABLE? List names of tables\n" + " If TABLE specified, only list tables matching\n" + " LIKE pattern TABLE.\n" + ".timeout MS Try opening locked tables for MS milliseconds\n" + ".trace FILE|off Output each SQL statement as it is run\n" + ".vfsname ?AUX? Print the name of the VFS stack\n" + ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"; static char zTimerHelp[] = - ".timer ON|OFF Turn the CPU timer measurement on or off\n" + ".timer ON|OFF Turn the CPU timer measurement on or off\n" /* Sandro Furieri 2008-06-20 */ "\n====================== SpatiaLite ========================================\n\n" ".charset Report the current locale charset setting\n\n" ".charset \n" " Set the charset encoding according to the command shell\n" @@ -2218,22 +2615,24 @@ " only elementary Geometries (one for each row) will be present\n" " arg_list: in_tbl geom out_tbl out_pk out_old_id\n\n" ".loadshp Loads a SHAPEFILE into a SpatiaLite table\n" " arg_list: shp_path table_name charset [SRID] [column_name]\n" " [pk_column] [geom_type] [2d | 3d] [compressed]\n" - " [with_spatial_index] [text_dates]\n" + " [with_spatial_index] [text_dates] [colname_case]\n" " geom_type={ AUTO | LINESTRING[ Z | M | ZM ]\n" " | MULTILINESTRING[ Z | M | ZM ]\n" " | POLYGON[ Z | M | ZM ]\n" " | MULTIPOLYGON[ Z | M | ZM ] }\n\n" ".dumpshp Dumps a SpatiaLite table into a SHAPEFILE\n" " arg_list: table_name column_name shp_path charset [geom_type]\n" + " [colname_case]\n" " geom_type={ POINT | LINESTRING | POLYGON | MULTIPOINT }\n\n" ".loaddbf Loads a DBF into a SpatiaLite table\n" - " arg_list: dbf_path table_name charset [pk_column] [text_dates]\n\n" + " arg_list: dbf_path table_name charset [pk_column]\n" + " [text_dates] [colname_case]\n\n" ".dumpdbf Dumps a SpatiaLite table into a DBF\n" - " arg_list: table_name dbf_path charset\n\n" + " arg_list: table_name dbf_path charset [colname_case]\n\n" #ifndef OMIT_FREEXL /* FreeXL is enabled */ ".loadxl Loads a XL spreadsheet (.xls) into a SpatiaLite table\n" " arg_list: xl_path table_name \n" " [worksheet_index [first_line_titles{0/1}]]\n\n" #endif /* end FreeXL support */ @@ -2264,45 +2663,51 @@ " arg_list: DXF_path [srid] [append] [dims] [mode]\n" " [rings] [table_prefix] [layer_name]\n" " append={Y|N} dims={AUTO|2D|3D} mode={DISTINCT|MIXED}\n" " rings={NONE|LINKED|UNLINKED}\n\n" /* end Sandro Furieri 2008-06-20 */ -; + ; /* Forward reference */ -static int process_input(struct callback_data *p, FILE *in, char *in_charset); +static int process_input (struct callback_data *p, FILE * in, char *in_charset); /* ** Make sure the database is open. If it is not, then open it. If ** the database fails to open, print an error message and exit. */ -static void open_db(struct callback_data *p){ - if( p->db==0 ){ - sqlite3_initialize(); - sqlite3_open(p->zDbFilename, &p->db); - db = p->db; - if( db && sqlite3_errcode(db)==SQLITE_OK ){ - sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, - shellstaticFunc, 0, 0); - } - if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){ - fprintf(stderr,"Error: unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(db)); - exit(1); - } - spatialite_init_ex (p->db, splite_cache, (splite_silent == 0) ? 1 : 0); +static void +open_db (struct callback_data *p) +{ + if (p->db == 0) + { + sqlite3_initialize (); + sqlite3_open (p->zDbFilename, &p->db); + db = p->db; + if (db && sqlite3_errcode (db) == SQLITE_OK) + { + sqlite3_create_function (db, "shellstatic", 0, SQLITE_UTF8, 0, + shellstaticFunc, 0, 0); + } + if (db == 0 || SQLITE_OK != sqlite3_errcode (db)) + { + fprintf (stderr, "Error: unable to open database \"%s\": %s\n", + p->zDbFilename, sqlite3_errmsg (db)); + exit (1); + } + spatialite_init_ex (p->db, splite_cache, + (splite_silent == 0) ? 1 : 0); #ifndef SQLITE_OMIT_LOAD_EXTENSION - sqlite3_enable_load_extension(p->db, 1); + sqlite3_enable_load_extension (p->db, 1); #endif /* Sandro Furieri 2009-11-08 */ sqlite3_exec (p->db, "PRAGMA foreign_keys = 1", NULL, 0, NULL); /* end Sandro Furieri 2008-11-08 */ /* Sandro Furieri 2010-08-07 */ spatialite_autocreate (p->db); /* end Sandro Furieri 2010-08-07 */ - } + } } /* ** Do C-language style dequoting. ** @@ -2310,160 +2715,221 @@ ** \n -> newline ** \r -> carriage return ** \NNN -> ascii character NNN in octal ** \\ -> backslash */ -static void resolve_backslashes(char *z){ - int i, j; - char c; - for(i=j=0; (c = z[i])!=0; i++, j++){ - if( c=='\\' ){ - c = z[++i]; - if( c=='n' ){ - c = '\n'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='r' ){ - c = '\r'; - }else if( c>='0' && c<='7' ){ - c -= '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - } - } - } - } - z[j] = c; - } - z[j] = 0; +static void +resolve_backslashes (char *z) +{ + int i, j; + char c; + for (i = j = 0; (c = z[i]) != 0; i++, j++) + { + if (c == '\\') + { + c = z[++i]; + if (c == 'n') + { + c = '\n'; + } + else if (c == 't') + { + c = '\t'; + } + else if (c == 'r') + { + c = '\r'; + } + else if (c >= '0' && c <= '7') + { + c -= '0'; + if (z[i + 1] >= '0' && z[i + 1] <= '7') + { + i++; + c = (c << 3) + z[i] - '0'; + if (z[i + 1] >= '0' && z[i + 1] <= '7') + { + i++; + c = (c << 3) + z[i] - '0'; + } + } + } + } + z[j] = c; + } + z[j] = 0; } /* ** Interpret zArg as a boolean value. Return either 0 or 1. */ -static int booleanValue(char *zArg){ - int val = atoi(zArg); - int j; - for(j=0; zArg[j]; j++){ - zArg[j] = ToLower(zArg[j]); - } - if( strcmp(zArg,"on")==0 ){ - val = 1; - }else if( strcmp(zArg,"yes")==0 ){ - val = 1; - } - return val; +static int +booleanValue (char *zArg) +{ + int val = atoi (zArg); + int j; + for (j = 0; zArg[j]; j++) + { + zArg[j] = ToLower (zArg[j]); + } + if (strcmp (zArg, "on") == 0) + { + val = 1; + } + else if (strcmp (zArg, "yes") == 0) + { + val = 1; + } + return val; } /* ** Close an output file, assuming it is not stderr or stdout */ -static void output_file_close(FILE *f){ - if( f && f!=stdout && f!=stderr ) fclose(f); +static void +output_file_close (FILE * f) +{ + if (f && f != stdout && f != stderr) + fclose (f); } /* ** Try to open an output file. The names "stdout" and "stderr" are ** recognized and do the right thing. NULL is returned if the output ** filename is "off". */ -static FILE *output_file_open(const char *zFile){ - FILE *f; - if( strcmp(zFile,"stdout")==0 ){ - f = stdout; - }else if( strcmp(zFile, "stderr")==0 ){ - f = stderr; - }else if( strcmp(zFile, "off")==0 ){ - f = 0; - }else{ - f = fopen(zFile, "wb"); - if( f==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); - } - } - return f; +static FILE * +output_file_open (const char *zFile) +{ + FILE *f; + if (strcmp (zFile, "stdout") == 0) + { + f = stdout; + } + else if (strcmp (zFile, "stderr") == 0) + { + f = stderr; + } + else if (strcmp (zFile, "off") == 0) + { + f = 0; + } + else + { + f = fopen (zFile, "wb"); + if (f == 0) + { + fprintf (stderr, "Error: cannot open \"%s\"\n", zFile); + } + } + return f; } /* ** A routine for handling output from sqlite3_trace(). */ -static void sql_trace_callback(void *pArg, const char *z){ - FILE *f = (FILE*)pArg; - if( f ) fprintf(f, "%s\n", z); +static void +sql_trace_callback (void *pArg, const char *z) +{ + FILE *f = (FILE *) pArg; + if (f) + fprintf (f, "%s\n", z); } /* ** A no-op routine that runs with the ".breakpoint" doc-command. This is ** a useful spot to set a debugger breakpoint. */ -static void test_breakpoint(void){ - static int nCall = 0; - nCall++; +static void +test_breakpoint (void) +{ + static int nCall = 0; + nCall++; } /* ** If an input line begins with "." then invoke this routine to ** process that line. ** ** Return 1 on error, 2 to exit, and 0 otherwise. */ -static int do_meta_command(char *zLine, struct callback_data *p){ - int i = 1; - int nArg = 0; - int n, c; - int rc = 0; - char *azArg[50]; - - /* Parse the input line into tokens. - */ - while( zLine[i] && nArg=2 ){ - const char *zFile, *zProc; - char *zErrMsg = 0; - zFile = azArg[1]; - zProc = nArg>=3 ? azArg[2] : 0; - open_db(p); - rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); - if( rc!=SQLITE_OK ){ - fprintf(stderr, "Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - } - }else + if (c == 'l' && strncmp (azArg[0], "load", n) == 0 && nArg >= 2) + { + const char *zFile, *zProc; + char *zErrMsg = 0; + zFile = azArg[1]; + zProc = nArg >= 3 ? azArg[2] : 0; + open_db (p); + rc = sqlite3_load_extension (p->db, zFile, zProc, &zErrMsg); + if (rc != SQLITE_OK) + { + fprintf (stderr, "Error: %s\n", zErrMsg); + sqlite3_free (zErrMsg); + rc = 1; + } + } + else #endif /* Sandro Furieri 2008-06-20 */ - if (c == 'c' && n > 1 && strncmp (azArg[0], "charset", n) == 0 && nArg == 1) + if (c == 'c' && n > 1 && strncmp (azArg[0], "charset", n) == 0 + && nArg == 1) { /* reporting the charset */ if (*spatialite_charset == '\0') { printf @@ -2482,34 +2948,62 @@ { /* setting the charset */ create_utf8_converter (azArg[1]); } else if (c == 'd' && n > 1 && strncmp (azArg[0], "dumpshp", n) == 0 - && (nArg == 5 || nArg == 6)) + && (nArg == 5 || nArg == 6 || nArg == 7)) { /* dumping a spatial table to SHAPEFILE */ char *table = azArg[1]; char *column = azArg[2]; char *shp_path = azArg[3]; char *outCS = azArg[4]; char *type = NULL; int rows; - if (nArg == 6) + int colname_case = GAIA_DBF_COLNAME_CASE_IGNORE; + if (nArg >= 6) type = azArg[5]; + if (nArg >= 7) + { + const char *pColnameCase = azArg[6]; + if (strcasecmp (pColnameCase, "UPPER") == 0 + || strcasecmp (pColnameCase, "UPPERCASE") == 0) + colname_case = GAIA_DBF_COLNAME_UPPERCASE; + else if (strcasecmp (pColnameCase, "LOWER") == 0 + || strcasecmp (pColnameCase, "LOWERCASE") == 0) + colname_case = GAIA_DBF_COLNAME_LOWERCASE; + else + colname_case = GAIA_DBF_COLNAME_CASE_IGNORE; + } open_db (p); - dump_shapefile (p->db, table, column, shp_path, outCS, type, 1, &rows, - NULL); + dump_shapefile_ex (p->db, table, column, shp_path, outCS, type, 1, + &rows, colname_case, NULL); } else if (c == 'd' && n > 1 && strncmp (azArg[0], "dumpdbf", n) == 0 - && (nArg == 4)) + && (nArg == 4 || nArg == 5)) { /* dumping a spatial table to DBF */ char *table = azArg[1]; char *dbf_path = azArg[2]; char *outCS = azArg[3]; + int rows; + int colname_case = GAIA_DBF_COLNAME_CASE_IGNORE; + if (nArg >= 5) + { + const char *pColnameCase = azArg[4]; + if (strcasecmp (pColnameCase, "UPPER") == 0 + || strcasecmp (pColnameCase, "UPPERCASE") == 0) + colname_case = GAIA_DBF_COLNAME_UPPERCASE; + else if (strcasecmp (pColnameCase, "LOWER") == 0 + || strcasecmp (pColnameCase, "LOWERCASE") == 0) + colname_case = GAIA_DBF_COLNAME_LOWERCASE; + else + colname_case = GAIA_DBF_COLNAME_CASE_IGNORE; + } open_db (p); - dump_dbf (p->db, table, dbf_path, outCS, NULL); + dump_dbf_ex2 (p->db, table, dbf_path, outCS, &rows, colname_case, + NULL); } else if (c == 'd' && n > 1 && strncmp (azArg[0], "dumpkml", n) == 0 && (nArg == 4 || nArg == 5 || nArg == 6 || nArg == 7)) { /* dumping a spatial table as KML file */ @@ -2560,23 +3054,25 @@ open_db (p); dump_geojson (p->db, table, geom, gml_path, precision, format); } else if (c == 'l' && n > 1 && strncmp (azArg[0], "loadshp", n) == 0 && (nArg == 4 || nArg == 5 || nArg == 6 || nArg == 7 || - nArg == 8 || nArg == 9 || nArg == 10 || nArg == 11 || nArg == 12)) + nArg == 8 || nArg == 9 || nArg == 10 || nArg == 11 + || nArg == 12 || nArg == 13)) { char *shp_path = azArg[1]; char *table = azArg[2]; char *inCS = azArg[3]; int srid = -1; int coerce2d = 0; int compressed = 0; int with_spatial_index = 0; int text_dates = 0; + int colname_case = GAIA_DBF_COLNAME_LOWERCASE; char *column = NULL; char *gtype = NULL; - char *pk = NULL; + char *pk = NULL; int rows; if (nArg >= 5) srid = atoi (azArg[4]); if (nArg >= 6) column = azArg[5]; @@ -2588,38 +3084,97 @@ { if (strcasecmp (azArg[8], "2d") == 0) coerce2d = 1; } if (nArg >= 10) - { + { if (strcasecmp (azArg[9], "compressed") == 0) compressed = 1; - } - if (nArg == 11) - with_spatial_index = 1; - if (nArg == 12) - text_dates = atoi(azArg[11]); - open_db (p); - load_shapefile_ex2 (p->db, shp_path, table, inCS, srid, column, gtype, pk, - coerce2d, compressed, 1, with_spatial_index, text_dates, - &rows, NULL); + if (strcasecmp (azArg[9], "yes") == 0) + compressed = 1; + if (strcasecmp (azArg[9], "true") == 0) + compressed = 1; + if (strcasecmp (azArg[9], "1") == 0) + compressed = 1; + } + if (nArg >= 11) + { + if (strcasecmp (azArg[10], "with_spatial_index") == 0) + with_spatial_index = 1; + if (strcasecmp (azArg[10], "yes") == 0) + with_spatial_index = 1; + if (strcasecmp (azArg[10], "true") == 0) + with_spatial_index = 1; + if (strcasecmp (azArg[10], "1") == 0) + with_spatial_index = 1; + } + if (nArg >= 12) + { + if (strcasecmp (azArg[11], "text_dates") == 0) + text_dates = 1; + if (strcasecmp (azArg[11], "yes") == 0) + text_dates = 1; + if (strcasecmp (azArg[11], "true") == 0) + text_dates = 1; + if (strcasecmp (azArg[11], "1") == 0) + text_dates = 1; + } + if (nArg >= 13) + { + const char *pColnameCase = azArg[12]; + if (strcasecmp (pColnameCase, "UPPER") == 0 + || strcasecmp (pColnameCase, "UPPERCASE") == 0) + colname_case = GAIA_DBF_COLNAME_UPPERCASE; + else if (strcasecmp (pColnameCase, "SAME") == 0 + || strcasecmp (pColnameCase, "SAMECASE") == 0) + colname_case = GAIA_DBF_COLNAME_CASE_IGNORE; + else + colname_case = GAIA_DBF_COLNAME_LOWERCASE; + } + open_db (p); + load_shapefile_ex3 (p->db, shp_path, table, inCS, srid, column, gtype, + pk, coerce2d, compressed, 1, with_spatial_index, + text_dates, &rows, colname_case, NULL); } else if (c == 'l' && n > 1 && strncmp (azArg[0], "loaddbf", n) == 0 - && (nArg == 4 || nArg == 5 || nArg == 6)) + && (nArg == 4 || nArg == 5 || nArg == 6 || nArg == 7)) { char *dbf_path = azArg[1]; char *table = azArg[2]; char *inCS = azArg[3]; - char *pk = NULL; - int text_dates = 0; + char *pk = NULL; + int text_dates = 0; + int colname_case = GAIA_DBF_COLNAME_LOWERCASE; int rows; - if (nArg == 5) - pk = azArg[4]; - if (nArg == 6) - text_dates = atoi(azArg[5]); + if (nArg >= 5) + pk = azArg[4]; + if (nArg >= 6) + { + if (strcasecmp (azArg[5], "text_dates") == 0) + text_dates = 1; + if (strcasecmp (azArg[5], "yes") == 0) + text_dates = 1; + if (strcasecmp (azArg[5], "true") == 0) + text_dates = 1; + if (strcasecmp (azArg[5], "1") == 0) + text_dates = 1; + } + if (nArg >= 7) + { + const char *pColnameCase = azArg[6]; + if (strcasecmp (pColnameCase, "UPPER") == 0 + || strcasecmp (pColnameCase, "UPPERCASE") == 0) + colname_case = GAIA_DBF_COLNAME_UPPERCASE; + else if (strcasecmp (pColnameCase, "SAME") == 0 + || strcasecmp (pColnameCase, "SAMECASE") == 0) + colname_case = GAIA_DBF_COLNAME_CASE_IGNORE; + else + colname_case = GAIA_DBF_COLNAME_LOWERCASE; + } open_db (p); - load_dbf_ex2 (p->db, dbf_path, table, pk, inCS, 1, text_dates, &rows, NULL); + load_dbf_ex3 (p->db, dbf_path, table, pk, inCS, 1, text_dates, &rows, + colname_case, NULL); } #ifndef OMIT_FREEXL /* FREEXL is enabled */ else if (c == 'l' && n > 1 && strncmp (azArg[0], "loadxl", n) == 0 && (nArg == 3 || nArg == 4 || nArg == 5)) { @@ -2640,117 +3195,126 @@ } #endif /* end FREEXL support */ else if (c == 'l' && n > 1 && strncmp (azArg[0], "loadwfs", n) == 0 && (nArg == 4 || nArg == 5 || nArg == 6 || nArg == 7 || nArg == 8)) { - char *path_or_url = azArg[1]; - char *layer_name = azArg[2]; - char *table = azArg[3]; - int swap_axes = 0; - int with_spatial_index = 0; - int page_size = -1; - char *pk = NULL; - char *err_msg = NULL; - int rows; + char *path_or_url = azArg[1]; + char *layer_name = azArg[2]; + char *table = azArg[3]; + int swap_axes = 0; + int with_spatial_index = 0; + int page_size = -1; + char *pk = NULL; + char *err_msg = NULL; + int rows; if (nArg >= 5) pk = azArg[4]; if (nArg >= 6) - { - if (strcasecmp(azArg[5], "swap") == 0 || - strcasecmp(azArg[5], "swap_axis") == 0 || - strcasecmp(azArg[5], "swap_axes") == 0) - swap_axes = 1; - } + { + if (strcasecmp (azArg[5], "swap") == 0 || + strcasecmp (azArg[5], "swap_axis") == 0 || + strcasecmp (azArg[5], "swap_axes") == 0) + swap_axes = 1; + } if (nArg >= 7) - page_size = atoi(azArg[6]); + page_size = atoi (azArg[6]); if (nArg == 8) with_spatial_index = 1; open_db (p); - if (load_from_wfs_paged (p->db, path_or_url, NULL, layer_name, swap_axes, table, pk, with_spatial_index, - page_size, &rows, &err_msg, wfs_page_done, NULL) == 0) - { - fprintf(stderr, "Unable to load data from WFS:\n"); - fprintf(stderr, "%s\n\n", err_msg); - } - else - fprintf(stderr, "inserted %d rows from WFS into table \"%s\"\n\n", rows, table); - if (err_msg) - free(err_msg); + if (load_from_wfs_paged + (p->db, path_or_url, NULL, layer_name, swap_axes, table, pk, + with_spatial_index, page_size, &rows, &err_msg, wfs_page_done, + NULL) == 0) + { + fprintf (stderr, "Unable to load data from WFS:\n"); + fprintf (stderr, "%s\n\n", err_msg); + } + else + fprintf (stderr, + "inserted %d rows from WFS into table \"%s\"\n\n", rows, + table); + if (err_msg) + free (err_msg); } else if (c == 'l' && n > 1 && strncmp (azArg[0], "loaddxf", n) == 0 && (nArg == 2 || (nArg >= 3 && nArg <= 9))) { char *dxf_path = azArg[1]; int srid = -1; - int append = 0; - int special_rings = GAIA_DXF_RING_NONE; - int mode = GAIA_DXF_IMPORT_BY_LAYER; - int force_dims = GAIA_DXF_AUTO_2D_3D; - char *prefix = NULL; - char *layer_name = NULL; - gaiaDxfParserPtr dxf = NULL; + int append = 0; + int special_rings = GAIA_DXF_RING_NONE; + int mode = GAIA_DXF_IMPORT_BY_LAYER; + int force_dims = GAIA_DXF_AUTO_2D_3D; + char *prefix = NULL; + char *layer_name = NULL; + gaiaDxfParserPtr dxf = NULL; if (nArg >= 3) - srid = atoi(azArg[2]); + srid = atoi (azArg[2]); if (nArg >= 4) - { - if (strcasecmp(azArg[3], "y") == 0 || - strcasecmp(azArg[3], "yes") == 0) - append = 1; - } + { + if (strcasecmp (azArg[3], "y") == 0 || + strcasecmp (azArg[3], "yes") == 0) + append = 1; + } if (nArg >= 5) - { - if (strcasecmp(azArg[4], "2D") == 0) - force_dims = GAIA_DXF_FORCE_2D; - if (strcasecmp(azArg[4], "3D") == 0) - force_dims = GAIA_DXF_FORCE_3D; - } + { + if (strcasecmp (azArg[4], "2D") == 0) + force_dims = GAIA_DXF_FORCE_2D; + if (strcasecmp (azArg[4], "3D") == 0) + force_dims = GAIA_DXF_FORCE_3D; + } if (nArg >= 6) - { - if (strcasecmp(azArg[5], "mixed") == 0) - mode = GAIA_DXF_IMPORT_MIXED; - } + { + if (strcasecmp (azArg[5], "mixed") == 0) + mode = GAIA_DXF_IMPORT_MIXED; + } if (nArg >= 7) - { - if (strcasecmp(azArg[6], "linked") == 0) - special_rings = GAIA_DXF_RING_LINKED; - if (strcasecmp(azArg[6], "unlinked") == 0) - special_rings = GAIA_DXF_RING_UNLINKED; - } - if (nArg >= 8) - { - if (strlen(azArg[7]) > 0) - prefix = azArg[7]; - } - if (nArg == 9) - { - if (strlen(azArg[8]) > 0) - layer_name = azArg[8]; - } - open_db (p); - /* creating a DXF parser */ - dxf = gaiaCreateDxfParser (srid, force_dims, prefix, layer_name, - special_rings); - if (dxf == NULL) - goto stop_dxf; - /* attempting to parse the DXF input file */ - if (gaiaParseDxfFile_r (splite_cache, dxf, dxf_path)) - { - /* loading into the DB */ - if (!gaiaLoadFromDxfParser (p->db, dxf, mode, append)) - fprintf (stderr, "DB error while loading: %s\n", dxf_path); - } - else - fprintf (stderr, "Unable to parse: %s\n", dxf_path); - fprintf(stderr, "\n*** DXF file successfully loaded\n"); -stop_dxf: - /* destroying the DXF parser */ - gaiaDestroyDxfParser (dxf); + { + if (strcasecmp (azArg[6], "linked") == 0) + special_rings = GAIA_DXF_RING_LINKED; + if (strcasecmp (azArg[6], "unlinked") == 0) + special_rings = GAIA_DXF_RING_UNLINKED; + } + if (nArg >= 8) + { + if (strlen (azArg[7]) > 0) + prefix = azArg[7]; + } + if (nArg == 9) + { + if (strlen (azArg[8]) > 0) + layer_name = azArg[8]; + } + open_db (p); + /* creating a DXF parser */ + dxf = gaiaCreateDxfParser (srid, force_dims, prefix, layer_name, + special_rings); + if (dxf == NULL) + goto stop_dxf; + /* attempting to parse the DXF input file */ + if (gaiaParseDxfFile_r (splite_cache, dxf, dxf_path)) + { + /* loading into the DB */ + if (!gaiaLoadFromDxfParser (p->db, dxf, mode, append)) + fprintf (stderr, "DB error while loading: %s\n", dxf_path); + } + else + fprintf (stderr, "Unable to parse: %s\n", dxf_path); + fprintf (stderr, "\n*** DXF file successfully loaded\n"); + stop_dxf: + /* destroying the DXF parser */ + gaiaDestroyDxfParser (dxf); } else if (c == 'r' && strncmp (azArg[0], "read", n) == 0) { FILE *alt; - if (nArg != 3) + char *arg2 = NULL; + if (nArg == 2) + ; + else if (nArg == 3) + arg2 = azArg[2]; + else { fprintf (stderr, "invalid arguments: .read script_path charset\n"); return rc; } @@ -2759,11 +3323,11 @@ { fprintf (stderr, "can't open \"%s\"\n", azArg[1]); } else { - process_input (p, alt, azArg[2]); + process_input (p, alt, arg2); fclose (alt); } } else if (c == 'c' && strncmp (azArg[0], "chkdupl", n) == 0 && nArg == 2) { @@ -2783,60 +3347,64 @@ char *table = azArg[1]; char *geometry = azArg[2]; char *report = azArg[3]; char *err_msg = NULL; open_db (p); - if (!check_geometry_column (p->db, table, geometry, report, NULL, NULL, &err_msg)) - { - fprintf(stderr, "check_geometry_column error:\n"); - fprintf(stderr, "%s\n\n", err_msg); - } - if (err_msg) - free(err_msg); + if (!check_geometry_column + (p->db, table, geometry, report, NULL, NULL, &err_msg)) + { + fprintf (stderr, "check_geometry_column error:\n"); + fprintf (stderr, "%s\n\n", err_msg); + } + if (err_msg) + free (err_msg); } else if (c == 'c' && strncmp (azArg[0], "checkgeom", n) == 0 && nArg == 2) { char *output_dir = azArg[1]; char *err_msg = NULL; open_db (p); if (!check_all_geometry_columns (p->db, output_dir, NULL, &err_msg)) - { - fprintf(stderr, "check_all_geometry_columns error:\n"); - fprintf(stderr, "%s\n\n", err_msg); - } - if (err_msg) - free(err_msg); + { + fprintf (stderr, "check_all_geometry_columns error:\n"); + fprintf (stderr, "%s\n\n", err_msg); + } + if (err_msg) + free (err_msg); } else if (c == 's' && strncmp (azArg[0], "sanegeom", n) == 0 && nArg == 5) { char *table = azArg[1]; char *geometry = azArg[2]; char *tmp_table = azArg[3]; char *report = azArg[4]; char *err_msg = NULL; open_db (p); - if (!sanitize_geometry_column (p->db, table, geometry, tmp_table, report, NULL, NULL, NULL, NULL, &err_msg)) - { - fprintf(stderr, "sanitize_geometry_column error:\n"); - fprintf(stderr, "%s\n\n", err_msg); - } - if (err_msg) - free(err_msg); + if (!sanitize_geometry_column + (p->db, table, geometry, tmp_table, report, NULL, NULL, NULL, + NULL, &err_msg)) + { + fprintf (stderr, "sanitize_geometry_column error:\n"); + fprintf (stderr, "%s\n\n", err_msg); + } + if (err_msg) + free (err_msg); } else if (c == 's' && strncmp (azArg[0], "sanegeom", n) == 0 && nArg == 3) { char *tmp_prefix = azArg[1]; char *output_dir = azArg[2]; char *err_msg = NULL; open_db (p); - if (!sanitize_all_geometry_columns (p->db, tmp_prefix, output_dir, NULL, &err_msg)) - { - fprintf(stderr, "sanitize_all_geometry_columns error:\n"); - fprintf(stderr, "%s\n\n", err_msg); - } - if (err_msg) - free(err_msg); + if (!sanitize_all_geometry_columns + (p->db, tmp_prefix, output_dir, NULL, &err_msg)) + { + fprintf (stderr, "sanitize_all_geometry_columns error:\n"); + fprintf (stderr, "%s\n\n", err_msg); + } + if (err_msg) + free (err_msg); } else if (c == 'e' && strncmp (azArg[0], "elemgeo", n) == 0 && nArg == 6) { char *inTable = azArg[1]; char *geom = azArg[2]; @@ -2850,1008 +3418,1283 @@ { sql_log_enabled = booleanValue (azArg[1]); } else if (c == 'd' && strncmp (azArg[0], "dropgeo", n) == 0 && nArg > 1) { - char *prefix; - char *table; - int ret; - int cnt0 = sqlite3_total_changes(p->db); - split_drop_name(azArg[1], &prefix, &table); - if (prefix != NULL && table != NULL) - ret = gaiaDropTableEx (p->db, prefix, table); - else + char *prefix; + char *table; + int ret; + int cnt0 = sqlite3_total_changes (p->db); + split_drop_name (azArg[1], &prefix, &table); + if (prefix != NULL && table != NULL) + ret = gaiaDropTableEx (p->db, prefix, table); + else ret = gaiaDropTable (p->db, azArg[1]); - if (ret) - { - int cnt1 = sqlite3_total_changes(p->db); - if (cnt1 > cnt0) - fprintf(stderr, "SpatialTable %s successfully removed\n", azArg[1]); - else - fprintf(stderr, "SpatialTable %s seems not to exist\n", azArg[1]); - } - else - fprintf(stderr, "ERROR: unable to remove SpatialTable %s\n", azArg[1]); - if (prefix != NULL) - free(prefix); - if (table != NULL) - free(table); - } else + if (ret) + { + int cnt1 = sqlite3_total_changes (p->db); + if (cnt1 > cnt0) + fprintf (stderr, "SpatialTable %s successfully removed\n", + azArg[1]); + else + fprintf (stderr, "SpatialTable %s seems not to exist\n", + azArg[1]); + } + else + fprintf (stderr, "ERROR: unable to remove SpatialTable %s\n", + azArg[1]); + if (prefix != NULL) + free (prefix); + if (table != NULL) + free (table); + } + else /* end sandro 2008-06-20 */ - if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){ - const char *zDestFile; - const char *zDb; - sqlite3 *pDest; - sqlite3_backup *pBackup; - if( nArg==2 ){ - zDestFile = azArg[1]; - zDb = "main"; - }else{ - zDestFile = azArg[2]; - zDb = azArg[1]; - } - rc = sqlite3_open(zDestFile, &pDest); - if( rc!=SQLITE_OK ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile); - sqlite3_close(pDest); - return 1; - } - open_db(p); - pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); - if( pBackup==0 ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - sqlite3_close(pDest); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} - sqlite3_backup_finish(pBackup); - if( rc==SQLITE_DONE ){ - rc = 0; - }else{ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - rc = 1; - } - sqlite3_close(pDest); - }else if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){ - bail_on_error = booleanValue(azArg[1]); - }else - - /* The undocumented ".breakpoint" command causes a call to the no-op - ** routine named test_breakpoint(). - */ - if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ - test_breakpoint(); - }else - - if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){ - struct callback_data data; - char *zErrMsg = 0; - open_db(p); - memcpy(&data, p, sizeof(data)); - data.showHeader = 1; - data.mode = MODE_Column; - data.colWidth[0] = 3; - data.colWidth[1] = 15; - data.colWidth[2] = 58; - data.cnt = 0; - sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - } - }else - - if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){ - open_db(p); - /* When playing back a "dump", the content might appear in an order - ** which causes immediate foreign key constraints to be violated. - ** So disable foreign-key constraint enforcement to prevent problems. */ - fprintf(p->out, "PRAGMA foreign_keys=OFF;\n"); - fprintf(p->out, "BEGIN TRANSACTION;\n"); - p->writableSchema = 0; - sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); - p->nErr = 0; - if( nArg==1 ){ - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" - ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE name=='sqlite_sequence'" - ); - run_table_dump_query(p, - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 - ); - }else{ - int i; - for(i=1; iwritableSchema ){ - fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); - p->writableSchema = 0; - } - sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); - sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); - fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); - }else - - if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){ - p->echoOn = booleanValue(azArg[1]); - }else - - if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){ - rc = 2; - }else - - if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){ - int val = nArg>=2 ? booleanValue(azArg[1]) : 1; - if(val == 1) { - if(!p->explainPrev.valid) { - p->explainPrev.valid = 1; - p->explainPrev.mode = p->mode; - p->explainPrev.showHeader = p->showHeader; - memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth)); - } - /* We could put this code under the !p->explainValid - ** condition so that it does not execute if we are already in - ** explain mode. However, always executing it allows us an easy - ** was to reset to explain mode in case the user previously - ** did an .explain followed by a .width, .mode or .header - ** command. - */ - p->mode = MODE_Explain; - p->showHeader = 1; - memset(p->colWidth,0,ArraySize(p->colWidth)); - p->colWidth[0] = 4; /* addr */ - p->colWidth[1] = 13; /* opcode */ - p->colWidth[2] = 4; /* P1 */ - p->colWidth[3] = 4; /* P2 */ - p->colWidth[4] = 4; /* P3 */ - p->colWidth[5] = 13; /* P4 */ - p->colWidth[6] = 2; /* P5 */ - p->colWidth[7] = 13; /* Comment */ - }else if (p->explainPrev.valid) { - p->explainPrev.valid = 0; - p->mode = p->explainPrev.mode; - p->showHeader = p->explainPrev.showHeader; - memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth)); - } - }else - - if( c=='h' && (strncmp(azArg[0], "header", n)==0 || - strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){ - p->showHeader = booleanValue(azArg[1]); - }else - - if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - fprintf(stderr,"%s",zHelp); - if( HAS_TIMER ){ - fprintf(stderr,"%s",zTimerHelp); - } - }else - - if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){ - char *zTable = azArg[2]; /* Insert data into this table */ - char *zFile = azArg[1]; /* The file from which to extract data */ - sqlite3_stmt *pStmt = NULL; /* A statement */ - int nCol; /* Number of columns in the table */ - int nByte; /* Number of bytes in an SQL string */ - int i, j; /* Loop counters */ - int nSep; /* Number of bytes in p->separator[] */ - char *zSql; /* An SQL statement */ - char *zLine; /* A single line of input from the file */ - char **azCol; /* zLine[] broken up into columns */ - char *zCommit; /* How to commit changes */ - FILE *in; /* The input file */ - int lineno = 0; /* Line number of input file */ - - open_db(p); - nSep = strlen30(p->separator); - if( nSep==0 ){ - fprintf(stderr, "Error: non-null separator required for import\n"); - return 1; - } - zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); - if( zSql==0 ){ - fprintf(stderr, "Error: out of memory\n"); - return 1; - } - nByte = strlen30(zSql); - rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( rc ){ - if (pStmt) sqlite3_finalize(pStmt); - fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); - return 1; - } - nCol = sqlite3_column_count(pStmt); - sqlite3_finalize(pStmt); - pStmt = 0; - if( nCol==0 ) return 0; /* no columns, no error */ - zSql = malloc( nByte + 20 + nCol*2 ); - if( zSql==0 ){ - fprintf(stderr, "Error: out of memory\n"); - return 1; - } - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable); - j = strlen30(zSql); - for(i=1; idb, zSql, -1, &pStmt, 0); - free(zSql); - if( rc ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); - if (pStmt) sqlite3_finalize(pStmt); - return 1; - } - in = fopen(zFile, "rb"); - if( in==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); - sqlite3_finalize(pStmt); - return 1; - } - azCol = malloc( sizeof(azCol[0])*(nCol+1) ); - if( azCol==0 ){ - fprintf(stderr, "Error: out of memory\n"); - fclose(in); - sqlite3_finalize(pStmt); - return 1; - } - sqlite3_exec(p->db, "BEGIN", 0, 0, 0); - zCommit = "COMMIT"; - while( (zLine = local_getline(0, in, 1))!=0 ){ - char *z, c; - int inQuote = 0; - lineno++; - azCol[0] = zLine; - for(i=0, z=zLine; (c = *z)!=0; z++){ - if( c=='"' ) inQuote = !inQuote; - if( c=='\n' ) lineno++; - if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){ - *z = 0; - i++; - if( idb, zCommit, 0, 0, 0); - }else - - if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){ - struct callback_data data; - char *zErrMsg = 0; - open_db(p); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.mode = MODE_List; - if( nArg==1 ){ - rc = sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND name NOT LIKE 'sqlite_%' " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - }else{ - zShellStatic = azArg[1]; - rc = sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - zShellStatic = 0; - } - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - }else if( rc != SQLITE_OK ){ - fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n"); - rc = 1; - } - }else - + if (c == 'b' && n >= 3 && strncmp (azArg[0], "backup", n) == 0 + && nArg > 1 && nArg < 4) + { + const char *zDestFile; + const char *zDb; + sqlite3 *pDest; + sqlite3_backup *pBackup; + if (nArg == 2) + { + zDestFile = azArg[1]; + zDb = "main"; + } + else + { + zDestFile = azArg[2]; + zDb = azArg[1]; + } + rc = sqlite3_open (zDestFile, &pDest); + if (rc != SQLITE_OK) + { + fprintf (stderr, "Error: cannot open \"%s\"\n", zDestFile); + sqlite3_close (pDest); + return 1; + } + open_db (p); + pBackup = sqlite3_backup_init (pDest, "main", p->db, zDb); + if (pBackup == 0) + { + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (pDest)); + sqlite3_close (pDest); + return 1; + } + while ((rc = sqlite3_backup_step (pBackup, 100)) == SQLITE_OK) + { + } + sqlite3_backup_finish (pBackup); + if (rc == SQLITE_DONE) + { + rc = 0; + } + else + { + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (pDest)); + rc = 1; + } + sqlite3_close (pDest); + } + else if (c == 'b' && n >= 3 && strncmp (azArg[0], "bail", n) == 0 + && nArg > 1 && nArg < 3) + { + bail_on_error = booleanValue (azArg[1]); + } + else + /* The undocumented ".breakpoint" command causes a call to the no-op + ** routine named test_breakpoint(). + */ + if (c == 'b' && n >= 3 && strncmp (azArg[0], "breakpoint", n) == 0) + { + test_breakpoint (); + } + else if (c == 'd' && n > 1 && strncmp (azArg[0], "databases", n) == 0 + && nArg == 1) + { + struct callback_data data; + char *zErrMsg = 0; + open_db (p); + memcpy (&data, p, sizeof (data)); + data.showHeader = 1; + data.mode = MODE_Column; + data.colWidth[0] = 3; + data.colWidth[1] = 15; + data.colWidth[2] = 58; + data.cnt = 0; + sqlite3_exec (p->db, "PRAGMA database_list; ", callback, &data, + &zErrMsg); + if (zErrMsg) + { + fprintf (stderr, "Error: %s\n", zErrMsg); + sqlite3_free (zErrMsg); + rc = 1; + } + } + else if (c == 'd' && strncmp (azArg[0], "dump", n) == 0 && nArg < 3) + { + open_db (p); + /* When playing back a "dump", the content might appear in an order + ** which causes immediate foreign key constraints to be violated. + ** So disable foreign-key constraint enforcement to prevent problems. */ + fprintf (p->out, "PRAGMA foreign_keys=OFF;\n"); + fprintf (p->out, "BEGIN TRANSACTION;\n"); + p->writableSchema = 0; + sqlite3_exec (p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, + 0, 0); + p->nErr = 0; + if (nArg == 1) + { + run_schema_dump_query (p, + "SELECT name, type, sql FROM sqlite_master " + "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"); + run_schema_dump_query (p, + "SELECT name, type, sql FROM sqlite_master " + "WHERE name=='sqlite_sequence'"); + run_table_dump_query (p, + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL AND type IN ('index','trigger','view')", + 0); + } + else + { + int i; + for (i = 1; i < nArg; i++) + { + zShellStatic = azArg[i]; + run_schema_dump_query (p, + "SELECT name, type, sql FROM sqlite_master " + "WHERE tbl_name LIKE shellstatic() AND type=='table'" + " AND sql NOT NULL"); + run_table_dump_query (p, + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" + " AND tbl_name LIKE shellstatic()", + 0); + zShellStatic = 0; + } + } + if (p->writableSchema) + { + fprintf (p->out, "PRAGMA writable_schema=OFF;\n"); + p->writableSchema = 0; + } + sqlite3_exec (p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); + sqlite3_exec (p->db, "RELEASE dump;", 0, 0, 0); + fprintf (p->out, + p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); + } + else if (c == 'e' && strncmp (azArg[0], "echo", n) == 0 && nArg > 1 + && nArg < 3) + { + p->echoOn = booleanValue (azArg[1]); + } + else if (c == 'e' && strncmp (azArg[0], "exit", n) == 0 && nArg == 1) + { + rc = 2; + } + else if (c == 'e' && strncmp (azArg[0], "explain", n) == 0 && nArg < 3) + { + int val = nArg >= 2 ? booleanValue (azArg[1]) : 1; + if (val == 1) + { + if (!p->explainPrev.valid) + { + p->explainPrev.valid = 1; + p->explainPrev.mode = p->mode; + p->explainPrev.showHeader = p->showHeader; + memcpy (p->explainPrev.colWidth, p->colWidth, + sizeof (p->colWidth)); + } + /* We could put this code under the !p->explainValid + ** condition so that it does not execute if we are already in + ** explain mode. However, always executing it allows us an easy + ** was to reset to explain mode in case the user previously + ** did an .explain followed by a .width, .mode or .header + ** command. + */ + p->mode = MODE_Explain; + p->showHeader = 1; + memset (p->colWidth, 0, ArraySize (p->colWidth)); + p->colWidth[0] = 4; /* addr */ + p->colWidth[1] = 13; /* opcode */ + p->colWidth[2] = 4; /* P1 */ + p->colWidth[3] = 4; /* P2 */ + p->colWidth[4] = 4; /* P3 */ + p->colWidth[5] = 13; /* P4 */ + p->colWidth[6] = 2; /* P5 */ + p->colWidth[7] = 13; /* Comment */ + } + else if (p->explainPrev.valid) + { + p->explainPrev.valid = 0; + p->mode = p->explainPrev.mode; + p->showHeader = p->explainPrev.showHeader; + memcpy (p->colWidth, p->explainPrev.colWidth, + sizeof (p->colWidth)); + } + } + else if (c == 'h' && (strncmp (azArg[0], "header", n) == 0 || + strncmp (azArg[0], "headers", n) == 0) && nArg > 1 + && nArg < 3) + { + p->showHeader = booleanValue (azArg[1]); + } + else if (c == 'h' && strncmp (azArg[0], "help", n) == 0) + { + fprintf (stderr, "%s", zHelp); + if (HAS_TIMER) + { + fprintf (stderr, "%s", zTimerHelp); + } + } + else if (c == 'i' && strncmp (azArg[0], "import", n) == 0 && nArg == 3) + { + char *zTable = azArg[2]; /* Insert data into this table */ + char *zFile = azArg[1]; /* The file from which to extract data */ + sqlite3_stmt *pStmt = NULL; /* A statement */ + int nCol; /* Number of columns in the table */ + int nByte; /* Number of bytes in an SQL string */ + int i, j; /* Loop counters */ + int nSep; /* Number of bytes in p->separator[] */ + char *zSql; /* An SQL statement */ + char *zLine; /* A single line of input from the file */ + char **azCol; /* zLine[] broken up into columns */ + char *zCommit; /* How to commit changes */ + FILE *in; /* The input file */ + int lineno = 0; /* Line number of input file */ + + open_db (p); + nSep = strlen30 (p->separator); + if (nSep == 0) + { + fprintf (stderr, + "Error: non-null separator required for import\n"); + return 1; + } + zSql = sqlite3_mprintf ("SELECT * FROM %s", zTable); + if (zSql == 0) + { + fprintf (stderr, "Error: out of memory\n"); + return 1; + } + nByte = strlen30 (zSql); + rc = sqlite3_prepare (p->db, zSql, -1, &pStmt, 0); + sqlite3_free (zSql); + if (rc) + { + if (pStmt) + sqlite3_finalize (pStmt); + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (db)); + return 1; + } + nCol = sqlite3_column_count (pStmt); + sqlite3_finalize (pStmt); + pStmt = 0; + if (nCol == 0) + return 0; /* no columns, no error */ + zSql = malloc (nByte + 20 + nCol * 2); + if (zSql == 0) + { + fprintf (stderr, "Error: out of memory\n"); + return 1; + } + sqlite3_snprintf (nByte + 20, zSql, "INSERT INTO %s VALUES(?", + zTable); + j = strlen30 (zSql); + for (i = 1; i < nCol; i++) + { + zSql[j++] = ','; + zSql[j++] = '?'; + } + zSql[j++] = ')'; + zSql[j] = 0; + rc = sqlite3_prepare (p->db, zSql, -1, &pStmt, 0); + free (zSql); + if (rc) + { + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (db)); + if (pStmt) + sqlite3_finalize (pStmt); + return 1; + } + in = fopen (zFile, "rb"); + if (in == 0) + { + fprintf (stderr, "Error: cannot open \"%s\"\n", zFile); + sqlite3_finalize (pStmt); + return 1; + } + azCol = malloc (sizeof (azCol[0]) * (nCol + 1)); + if (azCol == 0) + { + fprintf (stderr, "Error: out of memory\n"); + fclose (in); + sqlite3_finalize (pStmt); + return 1; + } + sqlite3_exec (p->db, "BEGIN", 0, 0, 0); + zCommit = "COMMIT"; + while ((zLine = local_getline (0, in, 1)) != 0) + { + char *z, c; + int inQuote = 0; + lineno++; + azCol[0] = zLine; + for (i = 0, z = zLine; (c = *z) != 0; z++) + { + if (c == '"') + inQuote = !inQuote; + if (c == '\n') + lineno++; + if (!inQuote && c == p->separator[0] + && strncmp (z, p->separator, nSep) == 0) + { + *z = 0; + i++; + if (i < nCol) + { + azCol[i] = &z[nSep]; + z += nSep - 1; + } + } + } /* end for */ + *z = 0; + if (i + 1 != nCol) + { + fprintf (stderr, + "Error: %s line %d: expected %d columns of data but found %d\n", + zFile, lineno, nCol, i + 1); + zCommit = "ROLLBACK"; + free (zLine); + rc = 1; + break; /* from while */ + } + for (i = 0; i < nCol; i++) + { + if (azCol[i][0] == '"') + { + int k; + for (z = azCol[i], j = 1, k = 0; z[j]; j++) + { + if (z[j] == '"') + { + j++; + if (z[j] == 0) + break; + } + z[k++] = z[j]; + } + z[k] = 0; + } + sqlite3_bind_text (pStmt, i + 1, azCol[i], -1, + SQLITE_STATIC); + } + sqlite3_step (pStmt); + rc = sqlite3_reset (pStmt); + free (zLine); + if (rc != SQLITE_OK) + { + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (db)); + zCommit = "ROLLBACK"; + rc = 1; + break; /* from while */ + } + } /* end while */ + free (azCol); + fclose (in); + sqlite3_finalize (pStmt); + sqlite3_exec (p->db, zCommit, 0, 0, 0); + } + else if (c == 'i' && strncmp (azArg[0], "indices", n) == 0 && nArg < 3) + { + struct callback_data data; + char *zErrMsg = 0; + open_db (p); + memcpy (&data, p, sizeof (data)); + data.showHeader = 0; + data.mode = MODE_List; + if (nArg == 1) + { + rc = sqlite3_exec (p->db, + "SELECT name FROM sqlite_master " + "WHERE type='index' AND name NOT LIKE 'sqlite_%' " + "UNION ALL " + "SELECT name FROM sqlite_temp_master " + "WHERE type='index' " + "ORDER BY 1", callback, &data, &zErrMsg); + } + else + { + zShellStatic = azArg[1]; + rc = sqlite3_exec (p->db, + "SELECT name FROM sqlite_master " + "WHERE type='index' AND tbl_name LIKE shellstatic() " + "UNION ALL " + "SELECT name FROM sqlite_temp_master " + "WHERE type='index' AND tbl_name LIKE shellstatic() " + "ORDER BY 1", callback, &data, &zErrMsg); + zShellStatic = 0; + } + if (zErrMsg) + { + fprintf (stderr, "Error: %s\n", zErrMsg); + sqlite3_free (zErrMsg); + rc = 1; + } + else if (rc != SQLITE_OK) + { + fprintf (stderr, + "Error: querying sqlite_master and sqlite_temp_master\n"); + rc = 1; + } + } + else #ifdef SQLITE_ENABLE_IOTRACE - if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ - extern void (*sqlite3IoTrace)(const char*, ...); - if( iotrace && iotrace!=stdout ) fclose(iotrace); - iotrace = 0; - if( nArg<2 ){ - sqlite3IoTrace = 0; - }else if( strcmp(azArg[1], "-")==0 ){ - sqlite3IoTrace = iotracePrintf; - iotrace = stdout; - }else{ - iotrace = fopen(azArg[1], "w"); - if( iotrace==0 ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); - sqlite3IoTrace = 0; - rc = 1; - }else{ - sqlite3IoTrace = iotracePrintf; - } - } - }else -#endif - - if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){ - const char *zFile = azArg[1]; - output_file_close(p->pLog); - p->pLog = output_file_open(zFile); - }else - - if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){ - int n2 = strlen30(azArg[1]); - if( (n2==4 && strncmp(azArg[1],"line",n2)==0) - || - (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){ - p->mode = MODE_Line; - }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0) - || - (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){ - p->mode = MODE_Column; - }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){ - p->mode = MODE_List; - }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){ - p->mode = MODE_Html; - }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){ - p->mode = MODE_Tcl; - }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){ - p->mode = MODE_Csv; - sqlite3_snprintf(sizeof(p->separator), p->separator, ","); - }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){ - p->mode = MODE_List; - sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); - }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - set_table_name(p, "table"); - }else { - fprintf(stderr,"Error: mode should be one of: " - "column csv html insert line list tabs tcl\n"); - rc = 1; - } - }else - - if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){ - int n2 = strlen30(azArg[1]); - if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - set_table_name(p, azArg[2]); - }else { - fprintf(stderr, "Error: invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[2]); - rc = 1; - } - }else - - if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { - sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, - "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); - }else - - if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ - if( p->outfile[0]=='|' ){ - pclose(p->out); - }else{ - output_file_close(p->out); - } - p->outfile[0] = 0; - if( azArg[1][0]=='|' ){ - p->out = popen(&azArg[1][1], "w"); - if( p->out==0 ){ - fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]); - p->out = stdout; - rc = 1; - }else{ - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); - } - }else{ - p->out = output_file_open(azArg[1]); - if( p->out==0 ){ - if( strcmp(azArg[1],"off")!=0 ){ - fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]); - } - p->out = stdout; - rc = 1; - } else { - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); - } - } - }else - - if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ - if( nArg >= 2) { - strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); - } - if( nArg >= 3) { - strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); - } - }else - - if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){ - rc = 2; - }else - - if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ - FILE *alt = fopen(azArg[1], "rb"); - if( alt==0 ){ - fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); - rc = 1; - }else{ - rc = process_input(p, alt, 0); - fclose(alt); - } - }else - - if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){ - const char *zSrcFile; - const char *zDb; - sqlite3 *pSrc; - sqlite3_backup *pBackup; - int nTimeout = 0; - - if( nArg==2 ){ - zSrcFile = azArg[1]; - zDb = "main"; - }else{ - zSrcFile = azArg[2]; - zDb = azArg[1]; - } - rc = sqlite3_open(zSrcFile, &pSrc); - if( rc!=SQLITE_OK ){ - fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); - sqlite3_close(pSrc); - return 1; - } - open_db(p); - pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); - if( pBackup==0 ){ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - sqlite3_close(pSrc); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK - || rc==SQLITE_BUSY ){ - if( rc==SQLITE_BUSY ){ - if( nTimeout++ >= 3 ) break; - sqlite3_sleep(100); - } - } - sqlite3_backup_finish(pBackup); - if( rc==SQLITE_DONE ){ - rc = 0; - }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - fprintf(stderr, "Error: source database is busy\n"); - rc = 1; - }else{ - fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - rc = 1; - } - sqlite3_close(pSrc); - }else - - if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){ - struct callback_data data; - char *zErrMsg = 0; - open_db(p); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.mode = MODE_Semi; - if( nArg>1 ){ - int i; - for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); - if( strcmp(azArg[1],"sqlite_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TABLE sqlite_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else{ - zShellStatic = azArg[1]; - rc = sqlite3_exec(p->db, - "SELECT sql FROM " - " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" - " FROM sqlite_master UNION ALL" - " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE lower(tbl_name) LIKE shellstatic()" - " AND type!='meta' AND sql NOTNULL " - "ORDER BY substr(type,2,1), " - " CASE type WHEN 'view' THEN rowid ELSE name END", - callback, &data, &zErrMsg); - zShellStatic = 0; - } - }else{ - rc = sqlite3_exec(p->db, - "SELECT sql FROM " - " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" - " FROM sqlite_master UNION ALL" - " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" - "ORDER BY substr(type,2,1)," - " CASE type WHEN 'view' THEN rowid ELSE name END", - callback, &data, &zErrMsg - ); - } - if( zErrMsg ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - }else if( rc != SQLITE_OK ){ - fprintf(stderr,"Error: querying schema information\n"); - rc = 1; - }else{ - rc = 0; - } - }else - - if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ - sqlite3_snprintf(sizeof(p->separator), p->separator, - "%.*s", (int)sizeof(p->separator)-1, azArg[1]); - }else - - if( c=='s' - && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) - ){ - char *zCmd; - int i; - if( nArg<2 ){ - fprintf(stderr, "Usage: .system COMMAND\n"); - rc = 1; - } - else { - zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); - for(i=2; iout,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); - fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off"); - fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); - fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); - fprintf(p->out,"%9.9s: ", "nullvalue"); - output_c_string(p->out, p->nullvalue); - fprintf(p->out, "\n"); - fprintf(p->out,"%9.9s: %s\n","output", - strlen30(p->outfile) ? p->outfile : "stdout"); - fprintf(p->out,"%9.9s: ", "separator"); - output_c_string(p->out, p->separator); - fprintf(p->out, "\n"); - fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); - fprintf(p->out,"%9.9s: ","width"); - for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { - fprintf(p->out,"%d ",p->colWidth[i]); - } - fprintf(p->out,"\n"); - }else - - if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){ - p->statsOn = booleanValue(azArg[1]); - }else - - if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){ - sqlite3_stmt *pStmt; - char **azResult; - int nRow, nAlloc; - char *zSql = 0; - int ii; - open_db(p); - rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); - if( rc ) return rc; - zSql = sqlite3_mprintf( - "SELECT name FROM sqlite_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1"); - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); - if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue; - if( strcmp(zDbName,"temp")==0 ){ - zSql = sqlite3_mprintf( - "%z UNION ALL " - "SELECT 'temp.' || name FROM sqlite_temp_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1", zSql); - }else{ - zSql = sqlite3_mprintf( - "%z UNION ALL " - "SELECT '%q.' || name FROM \"%w\".sqlite_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1", zSql, zDbName, zDbName); - } - } - sqlite3_finalize(pStmt); - zSql = sqlite3_mprintf("%z ORDER BY 1", zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( rc ) return rc; - nRow = nAlloc = 0; - azResult = 0; - if( nArg>1 ){ - sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); - }else{ - sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); - } - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - if( nRow>=nAlloc ){ - char **azNew; - int n = nAlloc*2 + 10; - azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n); - if( azNew==0 ){ - fprintf(stderr, "Error: out of memory\n"); - break; - } - nAlloc = n; - azResult = azNew; - } - azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); - if( azResult[nRow] ) nRow++; - } - sqlite3_finalize(pStmt); - if( nRow>0 ){ - int len, maxlen = 0; - int i, j; - int nPrintCol, nPrintRow; - for(i=0; imaxlen ) maxlen = len; - } - nPrintCol = 80/(maxlen+2); - if( nPrintCol<1 ) nPrintCol = 1; - nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; - for(i=0; i=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ - static const struct { - const char *zCtrlName; /* Name of a test-control option */ - int ctrlCode; /* Integer code for that option */ - } aCtrl[] = { - { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, - { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, - { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, - { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, - { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, - { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, - { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, - { "assert", SQLITE_TESTCTRL_ASSERT }, - { "always", SQLITE_TESTCTRL_ALWAYS }, - { "reserve", SQLITE_TESTCTRL_RESERVE }, - { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, - { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, - }; - int testctrl = -1; - int rc = 0; - int i, n; - open_db(p); - - /* convert testctrl text option to value. allow any unique prefix - ** of the option name, or a numerical value. */ - n = strlen30(azArg[1]); - for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ - if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ - if( testctrl<0 ){ - testctrl = aCtrl[i].ctrlCode; - }else{ - fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]); - testctrl = -1; - break; - } - } - } - if( testctrl<0 ) testctrl = atoi(azArg[1]); - if( (testctrlSQLITE_TESTCTRL_LAST) ){ - fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); - }else{ - switch(testctrl){ - - /* sqlite3_test_control(int, db, int) */ - case SQLITE_TESTCTRL_OPTIMIZATIONS: - case SQLITE_TESTCTRL_RESERVE: - if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); - rc = sqlite3_test_control(testctrl, p->db, opt); - printf("%d (0x%08x)\n", rc, rc); - } else { - fprintf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int) */ - case SQLITE_TESTCTRL_PRNG_SAVE: - case SQLITE_TESTCTRL_PRNG_RESTORE: - case SQLITE_TESTCTRL_PRNG_RESET: - if( nArg==2 ){ - rc = sqlite3_test_control(testctrl); - printf("%d (0x%08x)\n", rc, rc); - } else { - fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); - } - break; - - /* sqlite3_test_control(int, uint) */ - case SQLITE_TESTCTRL_PENDING_BYTE: - if( nArg==3 ){ - unsigned int opt = (unsigned int)atoi(azArg[2]); - rc = sqlite3_test_control(testctrl, opt); - printf("%d (0x%08x)\n", rc, rc); - } else { - fprintf(stderr,"Error: testctrl %s takes a single unsigned" - " int option\n", azArg[1]); - } - break; - - /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: - if( nArg==3 ){ - int opt = atoi(azArg[2]); - rc = sqlite3_test_control(testctrl, opt); - printf("%d (0x%08x)\n", rc, rc); - } else { - fprintf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int, char *) */ + if (c == 'i' && strncmp (azArg[0], "iotrace", n) == 0) + { + extern void (*sqlite3IoTrace) (const char *, ...); + if (iotrace && iotrace != stdout) + fclose (iotrace); + iotrace = 0; + if (nArg < 2) + { + sqlite3IoTrace = 0; + } + else if (strcmp (azArg[1], "-") == 0) + { + sqlite3IoTrace = iotracePrintf; + iotrace = stdout; + } + else + { + iotrace = fopen (azArg[1], "w"); + if (iotrace == 0) + { + fprintf (stderr, "Error: cannot open \"%s\"\n", azArg[1]); + sqlite3IoTrace = 0; + rc = 1; + } + else + { + sqlite3IoTrace = iotracePrintf; + } + } + } + else +#endif + + if (c == 'l' && strncmp (azArg[0], "log", n) == 0 && nArg >= 2) + { + const char *zFile = azArg[1]; + output_file_close (p->pLog); + p->pLog = output_file_open (zFile); + } + else if (c == 'm' && strncmp (azArg[0], "mode", n) == 0 && nArg == 2) + { + int n2 = strlen30 (azArg[1]); + if ((n2 == 4 && strncmp (azArg[1], "line", n2) == 0) + || (n2 == 5 && strncmp (azArg[1], "lines", n2) == 0)) + { + p->mode = MODE_Line; + } + else if ((n2 == 6 && strncmp (azArg[1], "column", n2) == 0) + || (n2 == 7 && strncmp (azArg[1], "columns", n2) == 0)) + { + p->mode = MODE_Column; + } + else if (n2 == 4 && strncmp (azArg[1], "list", n2) == 0) + { + p->mode = MODE_List; + } + else if (n2 == 4 && strncmp (azArg[1], "html", n2) == 0) + { + p->mode = MODE_Html; + } + else if (n2 == 3 && strncmp (azArg[1], "tcl", n2) == 0) + { + p->mode = MODE_Tcl; + } + else if (n2 == 3 && strncmp (azArg[1], "csv", n2) == 0) + { + p->mode = MODE_Csv; + sqlite3_snprintf (sizeof (p->separator), p->separator, ","); + } + else if (n2 == 4 && strncmp (azArg[1], "tabs", n2) == 0) + { + p->mode = MODE_List; + sqlite3_snprintf (sizeof (p->separator), p->separator, "\t"); + } + else if (n2 == 6 && strncmp (azArg[1], "insert", n2) == 0) + { + p->mode = MODE_Insert; + set_table_name (p, "table"); + } + else + { + fprintf (stderr, "Error: mode should be one of: " + "column csv html insert line list tabs tcl\n"); + rc = 1; + } + } + else if (c == 'm' && strncmp (azArg[0], "mode", n) == 0 && nArg == 3) + { + int n2 = strlen30 (azArg[1]); + if (n2 == 6 && strncmp (azArg[1], "insert", n2) == 0) + { + p->mode = MODE_Insert; + set_table_name (p, azArg[2]); + } + else + { + fprintf (stderr, "Error: invalid arguments: " + " \"%s\". Enter \".help\" for help\n", azArg[2]); + rc = 1; + } + } + else if (c == 'n' && strncmp (azArg[0], "nullvalue", n) == 0 && nArg == 2) + { + sqlite3_snprintf (sizeof (p->nullvalue), p->nullvalue, + "%.*s", (int) ArraySize (p->nullvalue) - 1, + azArg[1]); + } + else if (c == 'o' && strncmp (azArg[0], "output", n) == 0 && nArg == 2) + { + if (p->outfile[0] == '|') + { + pclose (p->out); + } + else + { + output_file_close (p->out); + } + p->outfile[0] = 0; + if (azArg[1][0] == '|') + { + p->out = popen (&azArg[1][1], "w"); + if (p->out == 0) + { + fprintf (stderr, "Error: cannot open pipe \"%s\"\n", + &azArg[1][1]); + p->out = stdout; + rc = 1; + } + else + { + sqlite3_snprintf (sizeof (p->outfile), p->outfile, "%s", + azArg[1]); + } + } + else + { + p->out = output_file_open (azArg[1]); + if (p->out == 0) + { + if (strcmp (azArg[1], "off") != 0) + { + fprintf (stderr, "Error: cannot write to \"%s\"\n", + azArg[1]); + } + p->out = stdout; + rc = 1; + } + else + { + sqlite3_snprintf (sizeof (p->outfile), p->outfile, "%s", + azArg[1]); + } + } + } + else if (c == 'p' && strncmp (azArg[0], "prompt", n) == 0 + && (nArg == 2 || nArg == 3)) + { + if (nArg >= 2) + { + strncpy (mainPrompt, azArg[1], + (int) ArraySize (mainPrompt) - 1); + } + if (nArg >= 3) + { + strncpy (continuePrompt, azArg[2], + (int) ArraySize (continuePrompt) - 1); + } + } + else if (c == 'q' && strncmp (azArg[0], "quit", n) == 0 && nArg == 1) + { + rc = 2; + } + else if (c == 'r' && n >= 3 && strncmp (azArg[0], "read", n) == 0 + && nArg > 0) + { + FILE *alt = fopen (azArg[1], "rb"); + if (alt == 0) + { + fprintf (stderr, "Error: cannot open \"%s\"\n", azArg[1]); + rc = 1; + } + else + { + rc = process_input (p, alt, 0); + fclose (alt); + } + } + else if (c == 'r' && n >= 3 && strncmp (azArg[0], "restore", n) == 0 + && nArg > 1 && nArg < 4) + { + const char *zSrcFile; + const char *zDb; + sqlite3 *pSrc; + sqlite3_backup *pBackup; + int nTimeout = 0; + + if (nArg == 2) + { + zSrcFile = azArg[1]; + zDb = "main"; + } + else + { + zSrcFile = azArg[2]; + zDb = azArg[1]; + } + rc = sqlite3_open (zSrcFile, &pSrc); + if (rc != SQLITE_OK) + { + fprintf (stderr, "Error: cannot open \"%s\"\n", zSrcFile); + sqlite3_close (pSrc); + return 1; + } + open_db (p); + pBackup = sqlite3_backup_init (p->db, zDb, pSrc, "main"); + if (pBackup == 0) + { + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (p->db)); + sqlite3_close (pSrc); + return 1; + } + while ((rc = sqlite3_backup_step (pBackup, 100)) == SQLITE_OK + || rc == SQLITE_BUSY) + { + if (rc == SQLITE_BUSY) + { + if (nTimeout++ >= 3) + break; + sqlite3_sleep (100); + } + } + sqlite3_backup_finish (pBackup); + if (rc == SQLITE_DONE) + { + rc = 0; + } + else if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) + { + fprintf (stderr, "Error: source database is busy\n"); + rc = 1; + } + else + { + fprintf (stderr, "Error: %s\n", sqlite3_errmsg (p->db)); + rc = 1; + } + sqlite3_close (pSrc); + } + else if (c == 's' && strncmp (azArg[0], "schema", n) == 0 && nArg < 3) + { + struct callback_data data; + char *zErrMsg = 0; + open_db (p); + memcpy (&data, p, sizeof (data)); + data.showHeader = 0; + data.mode = MODE_Semi; + if (nArg > 1) + { + int i; + for (i = 0; azArg[1][i]; i++) + azArg[1][i] = ToLower (azArg[1][i]); + if (strcmp (azArg[1], "sqlite_master") == 0) + { + char *new_argv[2], *new_colv[2]; + new_argv[0] = "CREATE TABLE sqlite_master (\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" " sql text\n" ")"; + new_argv[1] = 0; + new_colv[0] = "sql"; + new_colv[1] = 0; + callback (&data, 1, new_argv, new_colv); + rc = SQLITE_OK; + } + else if (strcmp (azArg[1], "sqlite_temp_master") == 0) + { + char *new_argv[2], *new_colv[2]; + new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" " sql text\n" ")"; + new_argv[1] = 0; + new_colv[0] = "sql"; + new_colv[1] = 0; + callback (&data, 1, new_argv, new_colv); + rc = SQLITE_OK; + } + else + { + zShellStatic = azArg[1]; + rc = sqlite3_exec (p->db, + "SELECT sql FROM " + " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" + " FROM sqlite_master UNION ALL" + " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " + "WHERE lower(tbl_name) LIKE shellstatic()" + " AND type!='meta' AND sql NOTNULL " + "ORDER BY substr(type,2,1), " + " CASE type WHEN 'view' THEN rowid ELSE name END", + callback, &data, &zErrMsg); + zShellStatic = 0; + } + } + else + { + rc = sqlite3_exec (p->db, + "SELECT sql FROM " + " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" + " FROM sqlite_master UNION ALL" + " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " + "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" + "ORDER BY substr(type,2,1)," + " CASE type WHEN 'view' THEN rowid ELSE name END", + callback, &data, &zErrMsg); + } + if (zErrMsg) + { + fprintf (stderr, "Error: %s\n", zErrMsg); + sqlite3_free (zErrMsg); + rc = 1; + } + else if (rc != SQLITE_OK) + { + fprintf (stderr, "Error: querying schema information\n"); + rc = 1; + } + else + { + rc = 0; + } + } + else if (c == 's' && strncmp (azArg[0], "separator", n) == 0 && nArg == 2) + { + sqlite3_snprintf (sizeof (p->separator), p->separator, + "%.*s", (int) sizeof (p->separator) - 1, azArg[1]); + } + else if (c == 's' + && (strncmp (azArg[0], "shell", n) == 0 + || strncmp (azArg[0], "system", n) == 0)) + { + char *zCmd; + int i; + if (nArg < 2) + { + fprintf (stderr, "Usage: .system COMMAND\n"); + rc = 1; + } + else + { + zCmd = + sqlite3_mprintf (strchr (azArg[1], ' ') == + 0 ? "%s" : "\"%s\"", azArg[1]); + for (i = 2; i < nArg; i++) + { + zCmd = + sqlite3_mprintf (strchr (azArg[i], ' ') == + 0 ? "%z %s" : "%z \"%s\"", zCmd, + azArg[i]); + } + (void) system (zCmd); + sqlite3_free (zCmd); + } + } + else if (c == 's' && strncmp (azArg[0], "show", n) == 0 && nArg == 1) + { + int i; + fprintf (p->out, "%9.9s: %s\n", "echo", p->echoOn ? "on" : "off"); + fprintf (p->out, "%9.9s: %s\n", "explain", + p->explainPrev.valid ? "on" : "off"); + fprintf (p->out, "%9.9s: %s\n", "headers", + p->showHeader ? "on" : "off"); + fprintf (p->out, "%9.9s: %s\n", "mode", modeDescr[p->mode]); + fprintf (p->out, "%9.9s: ", "nullvalue"); + output_c_string (p->out, p->nullvalue); + fprintf (p->out, "\n"); + fprintf (p->out, "%9.9s: %s\n", "output", + strlen30 (p->outfile) ? p->outfile : "stdout"); + fprintf (p->out, "%9.9s: ", "separator"); + output_c_string (p->out, p->separator); + fprintf (p->out, "\n"); + fprintf (p->out, "%9.9s: %s\n", "stats", p->statsOn ? "on" : "off"); + fprintf (p->out, "%9.9s: ", "width"); + for (i = 0; i < (int) ArraySize (p->colWidth) && p->colWidth[i] != 0; + i++) + { + fprintf (p->out, "%d ", p->colWidth[i]); + } + fprintf (p->out, "\n"); + } + else if (c == 's' && strncmp (azArg[0], "stats", n) == 0 && nArg > 1 + && nArg < 3) + { + p->statsOn = booleanValue (azArg[1]); + } + else if (c == 't' && n > 1 && strncmp (azArg[0], "tables", n) == 0 + && nArg < 3) + { + sqlite3_stmt *pStmt; + char **azResult; + int nRow, nAlloc; + char *zSql = 0; + int ii; + open_db (p); + rc = sqlite3_prepare_v2 (p->db, "PRAGMA database_list", -1, &pStmt, + 0); + if (rc) + return rc; + zSql = sqlite3_mprintf ("SELECT name FROM sqlite_master" + " WHERE type IN ('table','view')" + " AND name NOT LIKE 'sqlite_%%'" + " AND name LIKE ?1"); + while (sqlite3_step (pStmt) == SQLITE_ROW) + { + const char *zDbName = + (const char *) sqlite3_column_text (pStmt, 1); + if (zDbName == 0 || strcmp (zDbName, "main") == 0) + continue; + if (strcmp (zDbName, "temp") == 0) + { + zSql = sqlite3_mprintf ("%z UNION ALL " + "SELECT 'temp.' || name FROM sqlite_temp_master" + " WHERE type IN ('table','view')" + " AND name NOT LIKE 'sqlite_%%'" + " AND name LIKE ?1", zSql); + } + else + { + zSql = sqlite3_mprintf ("%z UNION ALL " + "SELECT '%q.' || name FROM \"%w\".sqlite_master" + " WHERE type IN ('table','view')" + " AND name NOT LIKE 'sqlite_%%'" + " AND name LIKE ?1", zSql, + zDbName, zDbName); + } + } + sqlite3_finalize (pStmt); + zSql = sqlite3_mprintf ("%z ORDER BY 1", zSql); + rc = sqlite3_prepare_v2 (p->db, zSql, -1, &pStmt, 0); + sqlite3_free (zSql); + if (rc) + return rc; + nRow = nAlloc = 0; + azResult = 0; + if (nArg > 1) + { + sqlite3_bind_text (pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); + } + else + { + sqlite3_bind_text (pStmt, 1, "%", -1, SQLITE_STATIC); + } + while (sqlite3_step (pStmt) == SQLITE_ROW) + { + if (nRow >= nAlloc) + { + char **azNew; + int n = nAlloc * 2 + 10; + azNew = + sqlite3_realloc (azResult, sizeof (azResult[0]) * n); + if (azNew == 0) + { + fprintf (stderr, "Error: out of memory\n"); + break; + } + nAlloc = n; + azResult = azNew; + } + azResult[nRow] = + sqlite3_mprintf ("%s", sqlite3_column_text (pStmt, 0)); + if (azResult[nRow]) + nRow++; + } + sqlite3_finalize (pStmt); + if (nRow > 0) + { + int len, maxlen = 0; + int i, j; + int nPrintCol, nPrintRow; + for (i = 0; i < nRow; i++) + { + len = strlen30 (azResult[i]); + if (len > maxlen) + maxlen = len; + } + nPrintCol = 80 / (maxlen + 2); + if (nPrintCol < 1) + nPrintCol = 1; + nPrintRow = (nRow + nPrintCol - 1) / nPrintCol; + for (i = 0; i < nPrintRow; i++) + { + for (j = i; j < nRow; j += nPrintRow) + { + char *zSp = j < nPrintRow ? "" : " "; + printf ("%s%-*s", zSp, maxlen, + azResult[j] ? azResult[j] : ""); + } + printf ("\n"); + } + } + for (ii = 0; ii < nRow; ii++) + sqlite3_free (azResult[ii]); + sqlite3_free (azResult); + } + else if (c == 't' && n >= 8 && strncmp (azArg[0], "testctrl", n) == 0 + && nArg >= 2) + { + static const struct + { + const char *zCtrlName; /* Name of a test-control option */ + int ctrlCode; /* Integer code for that option */ + } aCtrl[] = + { + { + "prng_save", SQLITE_TESTCTRL_PRNG_SAVE}, + { + "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE}, + { + "prng_reset", SQLITE_TESTCTRL_PRNG_RESET}, + { + "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST}, + { + "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL}, + { + "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS}, + { + "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE}, + { + "assert", SQLITE_TESTCTRL_ASSERT}, + { + "always", SQLITE_TESTCTRL_ALWAYS}, + { + "reserve", SQLITE_TESTCTRL_RESERVE}, + { + "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS}, + { + "iskeyword", SQLITE_TESTCTRL_ISKEYWORD}, + { + "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC},}; + int testctrl = -1; + int rc = 0; + int i, n; + open_db (p); + + /* convert testctrl text option to value. allow any unique prefix + ** of the option name, or a numerical value. */ + n = strlen30 (azArg[1]); + for (i = 0; i < (int) (sizeof (aCtrl) / sizeof (aCtrl[0])); i++) + { + if (strncmp (azArg[1], aCtrl[i].zCtrlName, n) == 0) + { + if (testctrl < 0) + { + testctrl = aCtrl[i].ctrlCode; + } + else + { + fprintf (stderr, "ambiguous option name: \"%s\"\n", + azArg[1]); + testctrl = -1; + break; + } + } + } + if (testctrl < 0) + testctrl = atoi (azArg[1]); + if ((testctrl < SQLITE_TESTCTRL_FIRST) + || (testctrl > SQLITE_TESTCTRL_LAST)) + { + fprintf (stderr, "Error: invalid testctrl option: %s\n", + azArg[1]); + } + else + { + switch (testctrl) + { + + /* sqlite3_test_control(int, db, int) */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: + case SQLITE_TESTCTRL_RESERVE: + if (nArg == 3) + { + int opt = (int) strtol (azArg[2], 0, 0); + rc = sqlite3_test_control (testctrl, p->db, opt); + printf ("%d (0x%08x)\n", rc, rc); + } + else + { + fprintf (stderr, + "Error: testctrl %s takes a single int option\n", + azArg[1]); + } + break; + + /* sqlite3_test_control(int) */ + case SQLITE_TESTCTRL_PRNG_SAVE: + case SQLITE_TESTCTRL_PRNG_RESTORE: + case SQLITE_TESTCTRL_PRNG_RESET: + if (nArg == 2) + { + rc = sqlite3_test_control (testctrl); + printf ("%d (0x%08x)\n", rc, rc); + } + else + { + fprintf (stderr, + "Error: testctrl %s takes no options\n", + azArg[1]); + } + break; + + /* sqlite3_test_control(int, uint) */ + case SQLITE_TESTCTRL_PENDING_BYTE: + if (nArg == 3) + { + unsigned int opt = (unsigned int) atoi (azArg[2]); + rc = sqlite3_test_control (testctrl, opt); + printf ("%d (0x%08x)\n", rc, rc); + } + else + { + fprintf (stderr, + "Error: testctrl %s takes a single unsigned" + " int option\n", azArg[1]); + } + break; + + /* sqlite3_test_control(int, int) */ + case SQLITE_TESTCTRL_ASSERT: + case SQLITE_TESTCTRL_ALWAYS: + if (nArg == 3) + { + int opt = atoi (azArg[2]); + rc = sqlite3_test_control (testctrl, opt); + printf ("%d (0x%08x)\n", rc, rc); + } + else + { + fprintf (stderr, + "Error: testctrl %s takes a single int option\n", + azArg[1]); + } + break; + + /* sqlite3_test_control(int, char *) */ #ifdef SQLITE_N_KEYWORD - case SQLITE_TESTCTRL_ISKEYWORD: - if( nArg==3 ){ - const char *opt = azArg[2]; - rc = sqlite3_test_control(testctrl, opt); - printf("%d (0x%08x)\n", rc, rc); - } else { - fprintf(stderr,"Error: testctrl %s takes a single char * option\n", - azArg[1]); - } - break; -#endif - - case SQLITE_TESTCTRL_BITVEC_TEST: - case SQLITE_TESTCTRL_FAULT_INSTALL: - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: - default: - fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", - azArg[1]); - break; - } - } - }else - - if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){ - open_db(p); - sqlite3_busy_timeout(p->db, atoi(azArg[1])); - }else - - if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 - && nArg==2 - ){ - enableTimer = booleanValue(azArg[1]); - }else - - if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){ - open_db(p); - output_file_close(p->traceOut); - p->traceOut = output_file_open(azArg[1]); + case SQLITE_TESTCTRL_ISKEYWORD: + if (nArg == 3) + { + const char *opt = azArg[2]; + rc = sqlite3_test_control (testctrl, opt); + printf ("%d (0x%08x)\n", rc, rc); + } + else + { + fprintf (stderr, + "Error: testctrl %s takes a single char * option\n", + azArg[1]); + } + break; +#endif + + case SQLITE_TESTCTRL_BITVEC_TEST: + case SQLITE_TESTCTRL_FAULT_INSTALL: + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: + case SQLITE_TESTCTRL_SCRATCHMALLOC: + default: + fprintf (stderr, + "Error: CLI support for testctrl %s not implemented\n", + azArg[1]); + break; + } + } + } + else if (c == 't' && n > 4 && strncmp (azArg[0], "timeout", n) == 0 + && nArg == 2) + { + open_db (p); + sqlite3_busy_timeout (p->db, atoi (azArg[1])); + } + else if (HAS_TIMER && c == 't' && n >= 5 + && strncmp (azArg[0], "timer", n) == 0 && nArg == 2) + { + enableTimer = booleanValue (azArg[1]); + } + else if (c == 't' && strncmp (azArg[0], "trace", n) == 0 && nArg > 1) + { + open_db (p); + output_file_close (p->traceOut); + p->traceOut = output_file_open (azArg[1]); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) - if( p->traceOut==0 ){ - sqlite3_trace(p->db, 0, 0); - }else{ - sqlite3_trace(p->db, sql_trace_callback, p->traceOut); - } + if (p->traceOut == 0) + { + sqlite3_trace (p->db, 0, 0); + } + else + { + sqlite3_trace (p->db, sql_trace_callback, p->traceOut); + } #endif - }else - - if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - printf("SQLite %s %s\n" /*extra-version-info*/, - sqlite3_libversion(), sqlite3_sourceid()); - }else - - if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ - const char *zDbName = nArg==2 ? azArg[1] : "main"; - char *zVfsName = 0; - if( p->db ){ + } + else if (c == 'v' && strncmp (azArg[0], "version", n) == 0) + { + printf ("SQLite %s %s\n" /*extra-version-info */ , + sqlite3_libversion (), sqlite3_sourceid ()); + } + else if (c == 'v' && strncmp (azArg[0], "vfsname", n) == 0) + { + const char *zDbName = nArg == 2 ? azArg[1] : "main"; + char *zVfsName = 0; + if (p->db) + { /* Sandro Furieri 1 November 2012 - depending on SQLite version */ #ifdef HAVE_DECL_SQLITE_FCNTL_VFSNAME - sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); - if( zVfsName ){ - printf("%s\n", zVfsName); - sqlite3_free(zVfsName); - } + sqlite3_file_control (p->db, zDbName, SQLITE_FCNTL_VFSNAME, + &zVfsName); + if (zVfsName) + { + printf ("%s\n", zVfsName); + sqlite3_free (zVfsName); + } #else - printf("FCNTL_VFSNAME: unsupported\n"); + printf ("FCNTL_VFSNAME: unsupported\n"); #endif /* end sandro 1 November 2012 */ - } - }else + } + } + else if (c == 'w' && strncmp (azArg[0], "width", n) == 0 && nArg > 1) + { + int j; + assert (nArg <= ArraySize (azArg)); + for (j = 1; j < nArg && j < ArraySize (p->colWidth); j++) + { + p->colWidth[j - 1] = atoi (azArg[j]); + } + } + else - if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ - int j; - assert( nArg<=ArraySize(azArg) ); - for(j=1; jcolWidth); j++){ - p->colWidth[j-1] = atoi(azArg[j]); - } - }else + { + fprintf (stderr, "Error: unknown command or invalid arguments: " + " \"%s\". Enter \".help\" for help\n", azArg[0]); + rc = 1; + } - { - fprintf(stderr, "Error: unknown command or invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[0]); - rc = 1; - } - - return rc; + return rc; } /* ** Return TRUE if a semicolon occurs anywhere in the first N characters ** of string z[]. */ -static int _contains_semicolon(const char *z, int N){ - int i; - for(i=0; iout); - free(zLine); - zLine = one_input_line(zSql, in); - if( zLine==0 ){ - /* End of input */ - if( stdin_is_interactive ) printf("\n"); - break; - } - if( seenInterrupt ){ - if( in!=0 ) break; - seenInterrupt = 0; - } - lineno++; - if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue; - if( zLine && zLine[0]=='.' && nSql==0 ){ - if( p->echoOn ) printf("%s\n", zLine); - rc = do_meta_command(zLine, p); - if( rc==2 ){ /* exit requested */ - break; - }else if( rc ){ - errCnt++; - } - continue; - } - if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){ - memcpy(zLine,";",2); - } - nSqlPrior = nSql; - if( zSql==0 ){ - int i; - for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} - if( zLine[i]!=0 ){ - nSql = strlen30(zLine); - zSql = malloc( nSql+3 ); - if( zSql==0 ){ - fprintf(stderr, "Error: out of memory\n"); - exit(1); - } - memcpy(zSql, zLine, nSql+1); - startline = lineno; - } - }else{ - int len = strlen30(zLine); - zSql = realloc( zSql, nSql + len + 4 ); - if( zSql==0 ){ - fprintf(stderr,"Error: out of memory\n"); - exit(1); - } - zSql[nSql++] = '\n'; - memcpy(&zSql[nSql], zLine, len+1); - nSql += len; - } - if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) - && sqlite3_complete(zSql) ){ - p->cnt = 0; - open_db(p); + while (errCnt == 0 || !bail_on_error || (in == 0 && stdin_is_interactive)) + { + fflush (stderr); + fflush (p->out); + free (zLine); + zLine = one_input_line (zSql, in); + if (zLine == 0) + { + /* End of input */ + if (stdin_is_interactive) + printf ("\n"); + break; + } + if (seenInterrupt) + { + if (in != 0) + break; + seenInterrupt = 0; + } + lineno++; + if ((zSql == 0 || zSql[0] == 0) && _all_whitespace (zLine)) + continue; + if (zLine && zLine[0] == '.' && nSql == 0) + { + if (p->echoOn) + printf ("%s\n", zLine); + rc = do_meta_command (zLine, p); + if (rc == 2) + { /* exit requested */ + break; + } + else if (rc) + { + errCnt++; + } + continue; + } + if (_is_command_terminator (zLine) && _is_complete (zSql, nSql)) + { + memcpy (zLine, ";", 2); + } + nSqlPrior = nSql; + if (zSql == 0) + { + int i; + for (i = 0; zLine[i] && IsSpace (zLine[i]); i++) + { + } + if (zLine[i] != 0) + { + nSql = strlen30 (zLine); + zSql = malloc (nSql + 3); + if (zSql == 0) + { + fprintf (stderr, "Error: out of memory\n"); + exit (1); + } + memcpy (zSql, zLine, nSql + 1); + startline = lineno; + } + } + else + { + int len = strlen30 (zLine); + zSql = realloc (zSql, nSql + len + 4); + if (zSql == 0) + { + fprintf (stderr, "Error: out of memory\n"); + exit (1); + } + zSql[nSql++] = '\n'; + memcpy (&zSql[nSql], zLine, len + 1); + nSql += len; + } + if (zSql && _contains_semicolon (&zSql[nSqlPrior], nSql - nSqlPrior) + && sqlite3_complete (zSql)) + { + p->cnt = 0; + open_db (p); /* Sandro Furieri - 11 July 2008 BEGIN_TIMER; rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); END_TIMER; */ - utf8len = strlen (zSql) * 4; - utf8Sql = malloc (utf8len); - if (utf8Sql == 0) - { - fprintf (stderr, "%s: out of memory!\n", Argv0); - exit (1); - } - strncpy (utf8Sql, zSql, utf8len - 1); - utf8Sql[utf8len - 1] = '\0'; - if (!in_charset) - { - /* assuming input is locale_charset encoded */ - convert_to_utf8 (utf8Sql, utf8len); - } - else - { - /* input has an explicit charset */ - convert_input_to_utf8 (utf8Sql, utf8len); - } - if (sql_log_enabled) - gaiaInsertIntoSqlLog(p->db, "spatialite CLI", utf8Sql, &sqllog_pk); - BEGIN_TIMER; - rc = sqlite3_exec (p->db, utf8Sql, callback, p, &zErrMsg); - END_TIMER; - if (sql_log_enabled) - gaiaUpdateSqlLog(p->db, sqllog_pk, (rc == SQLITE_OK) ? 1 : 0, zErrMsg); - free (utf8Sql); + utf8len = strlen (zSql) * 4; + utf8Sql = malloc (utf8len); + if (utf8Sql == 0) + { + fprintf (stderr, "%s: out of memory!\n", Argv0); + exit (1); + } + strncpy (utf8Sql, zSql, utf8len - 1); + utf8Sql[utf8len - 1] = '\0'; + if (!in_charset) + { + /* assuming input is locale_charset encoded */ + convert_to_utf8 (utf8Sql, utf8len); + } + else + { + /* input has an explicit charset */ + convert_input_to_utf8 (utf8Sql, utf8len); + } + if (sql_log_enabled) + gaiaInsertIntoSqlLog (p->db, "spatialite CLI", utf8Sql, + &sqllog_pk); + BEGIN_TIMER; + rc = sqlite3_exec (p->db, utf8Sql, callback, p, &zErrMsg); + END_TIMER; + if (sql_log_enabled) + gaiaUpdateSqlLog (p->db, sqllog_pk, + (rc == SQLITE_OK) ? 1 : 0, zErrMsg); + free (utf8Sql); /* End Sandro Furieri - 11 July 2008 */ - if( rc || zErrMsg ){ - char zPrefix[100]; - if( in!=0 || !stdin_is_interactive ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, - "Error: near line %d:", startline); - }else{ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); - } - if( zErrMsg!=0 ){ - fprintf(stderr, "%s %s\n", zPrefix, zErrMsg); - sqlite3_free(zErrMsg); - zErrMsg = 0; - }else{ - fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); - } - errCnt++; - } - free(zSql); - zSql = 0; - nSql = 0; - } - } - if( zSql ){ - if( !_all_whitespace(zSql) ){ - fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); - } - free(zSql); - } - free(zLine); + if (rc || zErrMsg) + { + char zPrefix[100]; + if (in != 0 || !stdin_is_interactive) + { + sqlite3_snprintf (sizeof (zPrefix), zPrefix, + "Error: near line %d:", + startline); + } + else + { + sqlite3_snprintf (sizeof (zPrefix), zPrefix, + "Error:"); + } + if (zErrMsg != 0) + { + fprintf (stderr, "%s %s\n", zPrefix, zErrMsg); + sqlite3_free (zErrMsg); + zErrMsg = 0; + } + else + { + fprintf (stderr, "%s %s\n", zPrefix, + sqlite3_errmsg (p->db)); + } + errCnt++; + } + free (zSql); + zSql = 0; + nSql = 0; + } + } + if (zSql) + { + if (!_all_whitespace (zSql)) + { + fprintf (stderr, "Error: incomplete SQL: %s\n", zSql); + } + free (zSql); + } + free (zLine); /* Sandro Furieri - 11 July 2008 */ - if (in_charset_to_utf8) - { - /* destroying input converter, if exists */ - iconv_close (in_charset_to_utf8); - in_charset_to_utf8 = NULL; - } + if (in_charset_to_utf8) + { + /* destroying input converter, if exists */ + iconv_close (in_charset_to_utf8); + in_charset_to_utf8 = NULL; + } /* End Sandro Furieri - 11 July 2008 */ - return errCnt; + return errCnt; } /* ** Return a pathname which is the user's home directory. A ** 0 return indicates an error of some kind. */ -static char *find_home_dir(void){ - static char *home_dir = NULL; - if( home_dir ) return home_dir; +static char * +find_home_dir (void) +{ + static char *home_dir = NULL; + if (home_dir) + return home_dir; #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL) - { - struct passwd *pwent; - uid_t uid = getuid(); - if( (pwent=getpwuid(uid)) != NULL) { - home_dir = pwent->pw_dir; + { + struct passwd *pwent; + uid_t uid = getuid (); + if ((pwent = getpwuid (uid)) != NULL) + { + home_dir = pwent->pw_dir; + } } - } #endif #if defined(_WIN32_WCE) - /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() - */ - home_dir = "/"; + /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() + */ + home_dir = "/"; #else #if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - home_dir = getenv("USERPROFILE"); - } + if (!home_dir) + { + home_dir = getenv ("USERPROFILE"); + } #endif - if (!home_dir) { - home_dir = getenv("HOME"); - } + if (!home_dir) + { + home_dir = getenv ("HOME"); + } #if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - char *zDrive, *zPath; - int n; - zDrive = getenv("HOMEDRIVE"); - zPath = getenv("HOMEPATH"); - if( zDrive && zPath ){ - n = strlen30(zDrive) + strlen30(zPath) + 1; - home_dir = malloc( n ); - if( home_dir==0 ) return 0; - sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); - return home_dir; - } - home_dir = "c:\\"; - } + if (!home_dir) + { + char *zDrive, *zPath; + int n; + zDrive = getenv ("HOMEDRIVE"); + zPath = getenv ("HOMEPATH"); + if (zDrive && zPath) + { + n = strlen30 (zDrive) + strlen30 (zPath) + 1; + home_dir = malloc (n); + if (home_dir == 0) + return 0; + sqlite3_snprintf (n, home_dir, "%s%s", zDrive, zPath); + return home_dir; + } + home_dir = "c:\\"; + } #endif #endif /* !_WIN32_WCE */ - if( home_dir ){ - int n = strlen30(home_dir) + 1; - char *z = malloc( n ); - if( z ) memcpy(z, home_dir, n); - home_dir = z; - } + if (home_dir) + { + int n = strlen30 (home_dir) + 1; + char *z = malloc (n); + if (z) + memcpy (z, home_dir, n); + home_dir = z; + } - return home_dir; + return home_dir; } /* ** Read input from the file given by sqliterc_override. Or if that ** parameter is NULL, take input from ~/.sqliterc ** ** Returns the number of errors. */ -static int process_sqliterc( - struct callback_data *p, /* Configuration data */ - const char *sqliterc_override /* Name of config file. NULL to use default */ -){ - char *home_dir = NULL; - const char *sqliterc = sqliterc_override; - char *zBuf = 0; - FILE *in = NULL; - int rc = 0; +static int +process_sqliterc (struct callback_data *p, /* Configuration data */ + const char *sqliterc_override /* Name of config file. NULL to use default */ + ) +{ + char *home_dir = NULL; + const char *sqliterc = sqliterc_override; + char *zBuf = 0; + FILE *in = NULL; + int rc = 0; - if (sqliterc == NULL) { - home_dir = find_home_dir(); - if( home_dir==0 ){ + if (sqliterc == NULL) + { + home_dir = find_home_dir (); + if (home_dir == 0) + { #if !defined(__RTP__) && !defined(_WRS_KERNEL) - fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0); + fprintf (stderr, + "%s: Error: cannot locate your home directory\n", + Argv0); #endif - return 1; - } - sqlite3_initialize(); - zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); - sqliterc = zBuf; - } - in = fopen(sqliterc,"rb"); - if( in ){ - if( stdin_is_interactive ){ - fprintf(stderr,"-- Loading resources from %s\n",sqliterc); - } - rc = process_input(p,in, 0); - fclose(in); - } - sqlite3_free(zBuf); - return rc; + return 1; + } + sqlite3_initialize (); + zBuf = sqlite3_mprintf ("%s/.sqliterc", home_dir); + sqliterc = zBuf; + } + in = fopen (sqliterc, "rb"); + if (in) + { + if (stdin_is_interactive) + { + fprintf (stderr, "-- Loading resources from %s\n", sqliterc); + } + rc = process_input (p, in, 0); + fclose (in); + } + sqlite3_free (zBuf); + return rc; } /* ** Show available command line options */ -static const char zOptions[] = - " -bail stop after hitting an error\n" - " -batch force batch I/O\n" - " -column set output mode to 'column'\n" - " -cmd command run \"command\" before reading stdin\n" - " -csv set output mode to 'csv'\n" - " -echo print commands before execution\n" - " -init filename read/process named file\n" - " -[no]header turn headers on or off\n" - " -help show this message\n" - " -html set output mode to HTML\n" - " -interactive force interactive I/O\n" - " -line set output mode to 'line'\n" - " -list set output mode to 'list'\n" - " -silent suppress the welcome message\n" +static const char zOptions[] = + " -bail stop after hitting an error\n" + " -batch force batch I/O\n" + " -column set output mode to 'column'\n" + " -cmd command run \"command\" before reading stdin\n" + " -csv set output mode to 'csv'\n" + " -echo print commands before execution\n" + " -init filename read/process named file\n" + " -[no]header turn headers on or off\n" + " -help show this message\n" + " -html set output mode to HTML\n" + " -interactive force interactive I/O\n" + " -line set output mode to 'line'\n" + " -list set output mode to 'list'\n" + " -silent suppress the welcome message\n" #ifdef SQLITE_ENABLE_MULTIPLEX - " -multiplex enable the multiplexor VFS\n" + " -multiplex enable the multiplexor VFS\n" #endif - " -nullvalue 'text' set text string for NULL values\n" - " -separator 'x' set output field separator (|)\n" - " -stats print memory stats before each finalize\n" - " -version show SQLite version\n" - " -vfs NAME use NAME as the default VFS\n" + " -nullvalue 'text' set text string for NULL values\n" + " -separator 'x' set output field separator (|)\n" + " -stats print memory stats before each finalize\n" + " -version show SQLite version\n" + " -vfs NAME use NAME as the default VFS\n" #ifdef SQLITE_ENABLE_VFSTRACE - " -vfstrace enable tracing of all VFS calls\n" + " -vfstrace enable tracing of all VFS calls\n" #endif -; -static void usage(int showDetail){ - fprintf(stderr, - "Usage: %s [OPTIONS] FILENAME [SQL]\n" - "FILENAME is the name of an SQLite database. A new database is created\n" - "if the file does not previously exist.\n", Argv0); - if( showDetail ){ - fprintf(stderr, "OPTIONS include:\n%s", zOptions); - }else{ - fprintf(stderr, "Use the -help option for additional information\n"); - } - exit(1); + ; +static void +usage (int showDetail) +{ + fprintf (stderr, + "Usage: %s [OPTIONS] FILENAME [SQL]\n" + "FILENAME is the name of an SQLite database. A new database is created\n" + "if the file does not previously exist.\n", Argv0); + if (showDetail) + { + fprintf (stderr, "OPTIONS include:\n%s", zOptions); + } + else + { + fprintf (stderr, "Use the -help option for additional information\n"); + } + exit (1); } /* ** Initialize the state information in data */ -static void main_init(struct callback_data *data) { - memset(data, 0, sizeof(*data)); - data->mode = MODE_List; - memcpy(data->separator,"|", 2); - data->showHeader = 0; +static void +main_init (struct callback_data *data) +{ + memset (data, 0, sizeof (*data)); + data->mode = MODE_List; + memcpy (data->separator, "|", 2); + data->showHeader = 0; /* Sandro Furieri 1 November 2012 - depending on SQLite version */ #ifdef HAVE_DECL_SQLITE_CONFIG_URI - sqlite3_config(SQLITE_CONFIG_URI, 1); + sqlite3_config (SQLITE_CONFIG_URI, 1); #endif /* end sandro 1 November 2012 */ - sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); - sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"spatialite> "); - sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); - sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); + sqlite3_config (SQLITE_CONFIG_LOG, shellLog, data); + sqlite3_snprintf (sizeof (mainPrompt), mainPrompt, "spatialite> "); + sqlite3_snprintf (sizeof (continuePrompt), continuePrompt, " ...> "); + sqlite3_config (SQLITE_CONFIG_SINGLETHREAD); } -int main(int argc, char **argv){ - char *zErrMsg = 0; - struct callback_data data; - const char *zInitFile = 0; - char *zFirstCmd = 0; - int i; - int rc = 0; - +int +main (int argc, char **argv) +{ + char *zErrMsg = 0; + struct callback_data data; + const char *zInitFile = 0; + char *zFirstCmd = 0; + int i; + int rc = 0; + /* initializing the SpatiaLite's internal cache */ - splite_cache = spatialite_alloc_connection (); + splite_cache = spatialite_alloc_connection (); +/* + * sandro: 2015-06-26 + * + * disabling version check as suggested by Fedora and Debian maintainers + * if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } - Argv0 = argv[0]; - main_init(&data); +*/ + + Argv0 = argv[0]; + main_init (&data); /* Sandro Furieri 30 May 2008 =========================== registering the SpatiaLite extension 2013-08-30: supporting "silent mode" */ - for(i=1; i0x7fff0000 ) szHeap = 0x7fff0000; - sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); + zSize = argv[++i]; + szHeap = atoi (zSize); + for (j = 0; (c = zSize[j]) != 0; j++) + { + if (c == 'M') + { + szHeap *= 1000000; + break; + } + if (c == 'K') + { + szHeap *= 1000; + break; + } + if (c == 'G') + { + szHeap *= 1000000000; + break; + } + } + if (szHeap > 0x7fff0000) + szHeap = 0x7fff0000; + sqlite3_config (SQLITE_CONFIG_HEAP, malloc ((int) szHeap), + (int) szHeap, 64); #endif #ifdef SQLITE_ENABLE_VFSTRACE - }else if( strcmp(z,"-vfstrace")==0 ){ - extern int vfstrace_register( - const char *zTraceName, - const char *zOldVfsName, - int (*xOut)(const char*,void*), - void *pOutArg, - int makeDefault - ); - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); + } + else if (strcmp (z, "-vfstrace") == 0) + { + extern int vfstrace_register (const char *zTraceName, + const char *zOldVfsName, + int (*xOut) (const char *, + void *), + void *pOutArg, int makeDefault); + vfstrace_register ("trace", 0, + (int (*)(const char *, void *)) fputs, + stderr, 1); #endif #ifdef SQLITE_ENABLE_MULTIPLEX - }else if( strcmp(z,"-multiplex")==0 ){ - extern int sqlite3_multiple_initialize(const char*,int); - sqlite3_multiplex_initialize(0, 1); + } + else if (strcmp (z, "-multiplex") == 0) + { + extern int sqlite3_multiple_initialize (const char *, int); + sqlite3_multiplex_initialize (0, 1); #endif - }else if( strcmp(z,"-vfs")==0 ){ - sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]); - if( pVfs ){ - sqlite3_vfs_register(pVfs, 1); - }else{ - fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]); - exit(1); + } + else if (strcmp (z, "-vfs") == 0) + { + sqlite3_vfs *pVfs = sqlite3_vfs_find (argv[++i]); + if (pVfs) + { + sqlite3_vfs_register (pVfs, 1); + } + else + { + fprintf (stderr, "no such VFS: \"%s\"\n", argv[i]); + exit (1); + } + } + } + if (i < argc) + { + data.zDbFilename = argv[i++]; } - } - } - if( i0 ){ - return rc; - } + /* Process the initialization file if there is one. If no -init option + ** is given on the command line, look for a file named ~/.sqliterc and + ** try to process it. + */ + rc = process_sqliterc (&data, zInitFile); + if (rc > 0) + { + return rc; + } - /* Make a second pass through the command-line argument and set - ** options. This second pass is delayed until after the initialization - ** file is processed so that the command-line arguments will override - ** settings in the initialization file. - */ - for(i=1; i=argc){ - fprintf(stderr,"%s: Error: missing argument for option: %s\n", - Argv0, z); - fprintf(stderr,"Use -help for a list of options.\n"); - return 1; - } - sqlite3_snprintf(sizeof(data.separator), data.separator, - "%.*s",(int)sizeof(data.separator)-1,argv[i]); - }else if( strcmp(z,"-nullvalue")==0 ){ - i++; - if(i>=argc){ - fprintf(stderr,"%s: Error: missing argument for option: %s\n", - Argv0, z); - fprintf(stderr,"Use -help for a list of options.\n"); - return 1; - } - sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, - "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]); - }else if( strcmp(z,"-header")==0 ){ - data.showHeader = 1; - }else if( strcmp(z,"-noheader")==0 ){ - data.showHeader = 0; - }else if( strcmp(z,"-echo")==0 ){ - data.echoOn = 1; - }else if( strcmp(z,"-stats")==0 ){ - data.statsOn = 1; - }else if( strcmp(z,"-bail")==0 ){ - bail_on_error = 1; - }else if( strcmp(z,"-silent")==0 ){ + /* Make a second pass through the command-line argument and set + ** options. This second pass is delayed until after the initialization + ** file is processed so that the command-line arguments will override + ** settings in the initialization file. + */ + for (i = 1; i < argc && argv[i][0] == '-'; i++) + { + char *z = argv[i]; + if (z[1] == '-') + { + z++; + } + if (strcmp (z, "-init") == 0) + { + i++; + } + else if (strcmp (z, "-html") == 0) + { + data.mode = MODE_Html; + } + else if (strcmp (z, "-list") == 0) + { + data.mode = MODE_List; + } + else if (strcmp (z, "-line") == 0) + { + data.mode = MODE_Line; + } + else if (strcmp (z, "-column") == 0) + { + data.mode = MODE_Column; + } + else if (strcmp (z, "-csv") == 0) + { + data.mode = MODE_Csv; + memcpy (data.separator, ",", 2); + } + else if (strcmp (z, "-separator") == 0) + { + i++; + if (i >= argc) + { + fprintf (stderr, + "%s: Error: missing argument for option: %s\n", + Argv0, z); + fprintf (stderr, "Use -help for a list of options.\n"); + return 1; + } + sqlite3_snprintf (sizeof (data.separator), data.separator, + "%.*s", (int) sizeof (data.separator) - 1, + argv[i]); + } + else if (strcmp (z, "-nullvalue") == 0) + { + i++; + if (i >= argc) + { + fprintf (stderr, + "%s: Error: missing argument for option: %s\n", + Argv0, z); + fprintf (stderr, "Use -help for a list of options.\n"); + return 1; + } + sqlite3_snprintf (sizeof (data.nullvalue), data.nullvalue, + "%.*s", (int) sizeof (data.nullvalue) - 1, + argv[i]); + } + else if (strcmp (z, "-header") == 0) + { + data.showHeader = 1; + } + else if (strcmp (z, "-noheader") == 0) + { + data.showHeader = 0; + } + else if (strcmp (z, "-echo") == 0) + { + data.echoOn = 1; + } + else if (strcmp (z, "-stats") == 0) + { + data.statsOn = 1; + } + else if (strcmp (z, "-bail") == 0) + { + bail_on_error = 1; + } + else if (strcmp (z, "-silent") == 0) + { /* sandro 2013-08-30 */ - splite_silent = 1; + splite_silent = 1; /* end sandro */ - }else if( strcmp(z,"-version")==0 ){ - printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); - return 0; - }else if( strcmp(z,"-interactive")==0 ){ - stdin_is_interactive = 1; - }else if( strcmp(z,"-batch")==0 ){ - stdin_is_interactive = 0; - }else if( strcmp(z,"-heap")==0 ){ - i++; - }else if( strcmp(z,"-vfs")==0 ){ - i++; + } + else if (strcmp (z, "-version") == 0) + { + printf ("%s %s\n", sqlite3_libversion (), sqlite3_sourceid ()); + return 0; + } + else if (strcmp (z, "-interactive") == 0) + { + stdin_is_interactive = 1; + } + else if (strcmp (z, "-batch") == 0) + { + stdin_is_interactive = 0; + } + else if (strcmp (z, "-heap") == 0) + { + i++; + } + else if (strcmp (z, "-vfs") == 0) + { + i++; #ifdef SQLITE_ENABLE_VFSTRACE - }else if( strcmp(z,"-vfstrace")==0 ){ - i++; + } + else if (strcmp (z, "-vfstrace") == 0) + { + i++; #endif #ifdef SQLITE_ENABLE_MULTIPLEX - }else if( strcmp(z,"-multiplex")==0 ){ - i++; + } + else if (strcmp (z, "-multiplex") == 0) + { + i++; #endif - }else if( strcmp(z,"-help")==0 ){ - usage(1); - }else if( strcmp(z,"-cmd")==0 ){ - if( i==argc-1 ) break; - i++; - z = argv[i]; - if( z[0]=='.' ){ - rc = do_meta_command(z, &data); - if( rc && bail_on_error ) return rc; - }else{ - open_db(&data); - rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg); - if( zErrMsg!=0 ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - if( bail_on_error ) return rc!=0 ? rc : 1; - }else if( rc!=0 ){ - fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z); - if( bail_on_error ) return rc; - } - } - }else{ - fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); - fprintf(stderr,"Use -help for a list of options.\n"); - return 1; - } - } + } + else if (strcmp (z, "-help") == 0) + { + usage (1); + } + else if (strcmp (z, "-cmd") == 0) + { + if (i == argc - 1) + break; + i++; + z = argv[i]; + if (z[0] == '.') + { + rc = do_meta_command (z, &data); + if (rc && bail_on_error) + return rc; + } + else + { + open_db (&data); + rc = shell_exec (data.db, z, shell_callback, &data, + &zErrMsg); + if (zErrMsg != 0) + { + fprintf (stderr, "Error: %s\n", zErrMsg); + if (bail_on_error) + return rc != 0 ? rc : 1; + } + else if (rc != 0) + { + fprintf (stderr, + "Error: unable to process SQL \"%s\"\n", + z); + if (bail_on_error) + return rc; + } + } + } + else + { + fprintf (stderr, "%s: Error: unknown option: %s\n", Argv0, z); + fprintf (stderr, "Use -help for a list of options.\n"); + return 1; + } + } - if( zFirstCmd ){ - /* Run just the command that follows the database name - */ - if( zFirstCmd[0]=='.' ){ - rc = do_meta_command(zFirstCmd, &data); - }else{ - open_db(&data); - rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg); - if( zErrMsg!=0 ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - return rc!=0 ? rc : 1; - }else if( rc!=0 ){ - fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd); - return rc; + if (zFirstCmd) + { + /* Run just the command that follows the database name + */ + if (zFirstCmd[0] == '.') + { + rc = do_meta_command (zFirstCmd, &data); + } + else + { + open_db (&data); + rc = shell_exec (data.db, zFirstCmd, shell_callback, &data, + &zErrMsg); + if (zErrMsg != 0) + { + fprintf (stderr, "Error: %s\n", zErrMsg); + return rc != 0 ? rc : 1; + } + else if (rc != 0) + { + fprintf (stderr, "Error: unable to process SQL \"%s\"\n", + zFirstCmd); + return rc; + } + } } - } - }else{ - /* Run commands received from standard input - */ - if( stdin_is_interactive ){ - char *zHome; - char *zHistory = 0; - int nHistory; + else + { + /* Run commands received from standard input + */ + if (stdin_is_interactive) + { + char *zHome; + char *zHistory = 0; + int nHistory; /* Sandro Furieri 2008-11-20 printf( "SQLite version %s %.19s\n" "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", sqlite3_libversion(), sqlite3_sourceid() ); */ - open_db(&data); - if (isatty (1)) - printf ("SQLite version ......: %s\n", - sqlite3_libversion ()); - auto_fdo_start (data.db); - if (isatty (1)) - printf ("Enter \".help\" for instructions\n"); + open_db (&data); + if (isatty (1)) + printf ("SQLite version ......: %s\n", + sqlite3_libversion ()); + auto_fdo_start (data.db); + if (isatty (1)) + printf ("Enter \".help\" for instructions\n"); /* end Sandro Furieri 2008-11-20 */ - printf( - "SQLite version %s %.19s\n" /*extra-version-info*/ - "Enter \".help\" for instructions\n" - "Enter SQL statements terminated with a \";\"\n", - sqlite3_libversion(), sqlite3_sourceid() - ); - zHome = find_home_dir(); - if( zHome ){ - nHistory = strlen30(zHome) + 20; - if( (zHistory = malloc(nHistory))!=0 ){ - sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); - } - } + printf ("SQLite version %s %.19s\n" /*extra-version-info */ + "Enter \".help\" for instructions\n" + "Enter SQL statements terminated with a \";\"\n", + sqlite3_libversion (), sqlite3_sourceid ()); + zHome = find_home_dir (); + if (zHome) + { + nHistory = strlen30 (zHome) + 20; + if ((zHistory = malloc (nHistory)) != 0) + { + sqlite3_snprintf (nHistory, zHistory, + "%s/.sqlite_history", zHome); + } + } #if defined(HAVE_READLINE) && HAVE_READLINE==1 - if( zHistory ) read_history(zHistory); + if (zHistory) + read_history (zHistory); #endif - rc = process_input(&data, 0, 0); - if( zHistory ){ - stifle_history(100); - write_history(zHistory); - free(zHistory); + rc = process_input (&data, 0, 0); + if (zHistory) + { + stifle_history (100); + write_history (zHistory); + free (zHistory); + } + } + else + { + rc = process_input (&data, stdin, 0); + } } - }else{ - rc = process_input(&data, stdin, 0); - } - } - set_table_name(&data, 0); + set_table_name (&data, 0); if (data.db) { /* Sandro Furieri 2008-11-20 */ auto_fdo_stop (data.db); /* end Sandro Furieri 2008-11-20 */ + +/* Sandro Furieri 2015-09-14 */ + spatialite_finalize_topologies (splite_cache); +/* end Sandro Furieri 2015-09-14 */ + if (sqlite3_close (data.db) != SQLITE_OK) { fprintf (stderr, "error closing database: %s\n", sqlite3_errmsg (data.db)); } @@ -4513,11 +5569,11 @@ /* Sandro Furieri 30 May 2008 =========================== memory cleanup for SpatiaLite extension */ - - spatialite_cleanup_ex (splite_cache); - spatialite_shutdown (); + + spatialite_cleanup_ex (splite_cache); + spatialite_shutdown (); - return rc; + return rc; } Index: shp_doctor.c ================================================================== --- shp_doctor.c +++ shp_doctor.c @@ -46,10 +46,11 @@ #else #include #endif #include +#include #define ARG_NONE 0 #define ARG_IN_PATH 1 #if defined(_WIN32) && !defined(__MINGW32__) @@ -1465,10 +1466,23 @@ fclose (fl_dbf); if (buf_dbf) free (buf_dbf); return; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "shp_doctor ..: %s\n", VERSION); + fprintf (stderr, "target CPU ..: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ..: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -1475,10 +1489,11 @@ fprintf (stderr, "\n\nusage: shp_doctor ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-i or --in-path pathname the SHP path [no suffix]\n"); fprintf (stderr, " or\n"); fprintf (stderr, " the full DBF path [-dbf]\n"); @@ -1520,10 +1535,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcasecmp (argv[i], "--in-path") == 0) { next_arg = ARG_IN_PATH; continue; ADDED shp_sanitize.c Index: shp_sanitize.c ================================================================== --- shp_sanitize.c +++ shp_sanitize.c @@ -0,0 +1,4326 @@ +/* +/ shp_sanitize +/ +/ an analysis / sanitizing tool for broken SHAPEFILES +/ +/ version 1.0, 2016 April 25 +/ +/ Author: Sandro Furieri a.furieri@lqt.it +/ +/ Copyright (C) 2016 Alessandro Furieri +/ +/ This program is free software: you can redistribute it and/or modify +/ it under the terms of the GNU General Public License as published by +/ the Free Software Foundation, either version 3 of the License, or +/ (at your option) any later version. +/ +/ This program is distributed in the hope that it will be useful, +/ but WITHOUT ANY WARRANTY; without even the implied warranty of +/ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/ GNU General Public License for more details. +/ +/ You should have received a copy of the GNU General Public License +/ along with this program. If not, see . +/ +*/ + +#ifndef _WIN32 +#include +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) +/* MSVC strictly requires this include [off_t] */ +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#if defined(_WIN32) && !defined(__MINGW32__) +#include +#include +#else +#include +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else +#include "config.h" +#endif + +#ifdef SPATIALITE_AMALGAMATION +#include +#else +#include +#endif + +#include +#include + +#define ARG_NONE 0 +#define ARG_IN_DIR 1 +#define ARG_OUT_DIR 2 + +#define SUFFIX_DISCARD 0 +#define SUFFIX_SHP 1 +#define SUFFIX_SHX 2 +#define SUFFIX_DBF 3 + +#define SHAPEFILE_NO_DATA 1e-38 + +#if defined(_WIN32) && !defined(__MINGW32__) +#define strcasecmp _stricmp +#endif /* not WIN32 */ + +struct shp_entry +{ +/* an item of the SHP list */ + char *base_name; + char *file_name; + int has_shp; + int has_shx; + int has_dbf; + struct shp_entry *next; +}; + +struct shp_list +{ +/* the SHP list */ + struct shp_entry *first; + struct shp_entry *last; +}; + +static struct shp_list * +alloc_shp_list (void) +{ +/* allocating an empty SHP list */ + struct shp_list *list = malloc (sizeof (struct shp_list)); + list->first = NULL; + list->last = NULL; + return list; +} + +static void +free_shp_list (struct shp_list *list) +{ +/* memory cleanup: freeing an SHP list */ + struct shp_entry *pi; + struct shp_entry *pin; + if (list == NULL) + return; + + pi = list->first; + while (pi != NULL) + { + pin = pi->next; + if (pi->base_name != NULL) + sqlite3_free (pi->base_name); + if (pi->file_name != NULL) + sqlite3_free (pi->file_name); + free (pi); + pi = pin; + } + free (list); +} + +static void +do_add_shapefile (struct shp_list *list, char *base_name, char *file_name, + int suffix) +{ +/* adding a possible SHP to the list */ + struct shp_entry *pi; + if (list == NULL) + return; + + pi = list->first; + while (pi != NULL) + { + /* searching if already defined */ + if (strcmp (pi->base_name, base_name) == 0) + { + switch (suffix) + { + case SUFFIX_SHP: + pi->has_shp = 1; + break; + case SUFFIX_SHX: + pi->has_shx = 1; + break; + case SUFFIX_DBF: + pi->has_dbf = 1; + break; + }; + sqlite3_free (base_name); + sqlite3_free (file_name); + return; + } + pi = pi->next; + } + +/* adding a new SHP entry */ + pi = malloc (sizeof (struct shp_entry)); + pi->base_name = base_name; + pi->file_name = file_name; + pi->has_shp = 0; + pi->has_shx = 0; + pi->has_dbf = 0; + pi->next = NULL; + + switch (suffix) + { + case SUFFIX_SHP: + pi->has_shp = 1; + break; + case SUFFIX_SHX: + pi->has_shx = 1; + break; + case SUFFIX_DBF: + pi->has_dbf = 1; + break; + }; + + if (list->first == NULL) + list->first = pi; + if (list->last != NULL) + list->last->next = pi; + list->last = pi; +} + +static int +test_valid_shp (struct shp_entry *p) +{ +/* testing for a valid SHP candidate */ + if (p == NULL) + return 0; + if (p->has_shp && p->has_shx && p->has_dbf) + return 1; + return 0; +} + +static gaiaShapefilePtr +allocShapefile () +{ +/* allocates and initializes the Shapefile object */ + gaiaShapefilePtr shp = malloc (sizeof (gaiaShapefile)); + shp->endian_arch = 1; + shp->Path = NULL; + shp->Shape = -1; + shp->EffectiveType = GAIA_UNKNOWN; + shp->EffectiveDims = GAIA_XY; + shp->flShp = NULL; + shp->flShx = NULL; + shp->flDbf = NULL; + shp->Dbf = NULL; + shp->ShpBfsz = 0; + shp->BufShp = NULL; + shp->BufDbf = NULL; + shp->DbfHdsz = 0; + shp->DbfReclen = 0; + shp->DbfSize = 0; + shp->DbfRecno = 0; + shp->ShpSize = 0; + shp->ShxSize = 0; + shp->MinX = DBL_MAX; + shp->MinY = DBL_MAX; + shp->MaxX = -DBL_MAX; + shp->MaxY = -DBL_MAX; + shp->Valid = 0; + shp->IconvObj = NULL; + shp->LastError = NULL; + return shp; +} + +static void +freeShapefile (gaiaShapefilePtr shp) +{ +/* frees all memory allocations related to the Shapefile object */ + if (shp->Path) + free (shp->Path); + if (shp->flShp) + fclose (shp->flShp); + if (shp->flShx) + fclose (shp->flShx); + if (shp->flDbf) + fclose (shp->flDbf); + if (shp->Dbf) + gaiaFreeDbfList (shp->Dbf); + if (shp->BufShp) + free (shp->BufShp); + if (shp->BufDbf) + free (shp->BufDbf); + if (shp->LastError) + free (shp->LastError); + free (shp); +} + +static void +openShpRead (gaiaShapefilePtr shp, const char *path, double *MinX, double *MinY, + double *MaxX, double *MaxY, int *mismatching) +{ +/* trying to open the shapefile and initial checkings */ + FILE *fl_shx = NULL; + FILE *fl_shp = NULL; + FILE *fl_dbf = NULL; + char xpath[1024]; + int rd; + unsigned char buf_shx[256]; + unsigned char *buf_shp = NULL; + int buf_size = 1024; + int shape; + unsigned char bf[1024]; + int dbf_size; + int dbf_reclen = 0; + int off_dbf; + int ind; + char field_name[2048]; + char *sys_err; + char errMsg[1024]; + double minx; + double miny; + double maxx; + double maxy; + int len; + int endian_arch = gaiaEndianArch (); + gaiaDbfListPtr dbf_list = NULL; + if (shp->flShp != NULL || shp->flShx != NULL || shp->flDbf != NULL) + { + sprintf (errMsg, + "attempting to reopen an already opened Shapefile\n"); + goto unsupported_conversion; + } + sprintf (xpath, "%s.shx", path); + fl_shx = fopen (xpath, "rb"); + if (!fl_shx) + { + sys_err = strerror (errno); + sprintf (errMsg, "unable to open '%s' for reading: %s", xpath, + sys_err); + goto no_file; + } + sprintf (xpath, "%s.shp", path); + fl_shp = fopen (xpath, "rb"); + if (!fl_shp) + { + sys_err = strerror (errno); + sprintf (errMsg, "unable to open '%s' for reading: %s", xpath, + sys_err); + goto no_file; + } + sprintf (xpath, "%s.dbf", path); + fl_dbf = fopen (xpath, "rb"); + if (!fl_dbf) + { + sys_err = strerror (errno); + sprintf (errMsg, "unable to open '%s' for reading: %s", xpath, + sys_err); + goto no_file; + } +/* reading SHX file header */ + rd = fread (buf_shx, sizeof (unsigned char), 100, fl_shx); + if (rd != 100) + goto error; + if (gaiaImport32 (buf_shx + 0, GAIA_BIG_ENDIAN, endian_arch) != 9994) /* checks the SHX magic number */ + goto error; + *MinX = gaiaImport64 (buf_shx + 36, GAIA_LITTLE_ENDIAN, endian_arch); + *MinY = gaiaImport64 (buf_shx + 44, GAIA_LITTLE_ENDIAN, endian_arch); + *MaxX = gaiaImport64 (buf_shx + 52, GAIA_LITTLE_ENDIAN, endian_arch); + *MaxY = gaiaImport64 (buf_shx + 60, GAIA_LITTLE_ENDIAN, endian_arch); +/* reading SHP file header */ + buf_shp = malloc (sizeof (unsigned char) * buf_size); + rd = fread (buf_shp, sizeof (unsigned char), 100, fl_shp); + if (rd != 100) + goto error; + if (gaiaImport32 (buf_shp + 0, GAIA_BIG_ENDIAN, endian_arch) != 9994) /* checks the SHP magic number */ + goto error; + minx = gaiaImport64 (buf_shp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + miny = gaiaImport64 (buf_shp + 44, GAIA_LITTLE_ENDIAN, endian_arch); + maxx = gaiaImport64 (buf_shp + 52, GAIA_LITTLE_ENDIAN, endian_arch); + maxy = gaiaImport64 (buf_shp + 60, GAIA_LITTLE_ENDIAN, endian_arch); + *mismatching = 0; + if (*MinX != minx || *MinY != miny || *MaxX != maxx || *MaxY != maxy) + { + fprintf (stderr, + "\t\tHEADERS: found mismatching BBOX between .shx and .shp\n"); + *mismatching = 1; + } + shape = gaiaImport32 (buf_shp + 32, GAIA_LITTLE_ENDIAN, endian_arch); + if (shape == GAIA_SHP_POINT || shape == GAIA_SHP_POINTZ + || shape == GAIA_SHP_POINTM || shape == GAIA_SHP_POLYLINE + || shape == GAIA_SHP_POLYLINEZ || shape == GAIA_SHP_POLYLINEM + || shape == GAIA_SHP_POLYGON || shape == GAIA_SHP_POLYGONZ + || shape == GAIA_SHP_POLYGONM || shape == GAIA_SHP_MULTIPOINT + || shape == GAIA_SHP_MULTIPOINTZ || shape == GAIA_SHP_MULTIPOINTM) + ; + else + goto unsupported; +/* reading DBF file header */ + rd = fread (bf, sizeof (unsigned char), 32, fl_dbf); + if (rd != 32) + goto error; + switch (*bf) + { + /* checks the DBF magic number */ + case 0x03: + case 0x83: + break; + case 0x02: + case 0xF8: + sprintf (errMsg, "'%s'\ninvalid magic number %02x [FoxBASE format]", + path, *bf); + goto dbf_bad_magic; + case 0xF5: + sprintf (errMsg, + "'%s'\ninvalid magic number %02x [FoxPro 2.x (or earlier) format]", + path, *bf); + goto dbf_bad_magic; + case 0x30: + case 0x31: + case 0x32: + sprintf (errMsg, + "'%s'\ninvalid magic number %02x [Visual FoxPro format]", + path, *bf); + goto dbf_bad_magic; + case 0x43: + case 0x63: + case 0xBB: + case 0xCB: + sprintf (errMsg, "'%s'\ninvalid magic number %02x [dBASE IV format]", + path, *bf); + goto dbf_bad_magic; + default: + sprintf (errMsg, "'%s'\ninvalid magic number %02x [unknown format]", + path, *bf); + goto dbf_bad_magic; + }; + dbf_size = gaiaImport16 (bf + 8, GAIA_LITTLE_ENDIAN, endian_arch); + dbf_reclen = gaiaImport16 (bf + 10, GAIA_LITTLE_ENDIAN, endian_arch); + dbf_size--; + off_dbf = 0; + dbf_list = gaiaAllocDbfList (); + for (ind = 32; ind < dbf_size; ind += 32) + { + /* fetches DBF fields definitions */ + rd = fread (bf, sizeof (unsigned char), 32, fl_dbf); + if (rd != 32) + goto error; + if (*(bf + 11) == 'M') + { + /* skipping any MEMO field */ + memcpy (field_name, bf, 11); + field_name[11] = '\0'; + off_dbf += *(bf + 16); + fprintf (stderr, + "WARNING: column \"%s\" is of the MEMO type and will be ignored\n", + field_name); + continue; + } + memcpy (field_name, bf, 11); + field_name[11] = '\0'; + gaiaAddDbfField (dbf_list, field_name, *(bf + 11), off_dbf, + *(bf + 16), *(bf + 17)); + off_dbf += *(bf + 16); + } + if (!gaiaIsValidDbfList (dbf_list)) + { + /* invalid DBF */ + goto illegal_dbf; + } + len = strlen (path); + shp->Path = malloc (len + 1); + strcpy (shp->Path, path); + shp->ReadOnly = 1; + shp->Shape = shape; + switch (shape) + { + /* setting up a prudential geometry type */ + case GAIA_SHP_POINT: + case GAIA_SHP_POINTZ: + case GAIA_SHP_POINTM: + shp->EffectiveType = GAIA_POINT; + break; + case GAIA_SHP_POLYLINE: + case GAIA_SHP_POLYLINEZ: + case GAIA_SHP_POLYLINEM: + shp->EffectiveType = GAIA_MULTILINESTRING; + break; + case GAIA_SHP_POLYGON: + case GAIA_SHP_POLYGONZ: + case GAIA_SHP_POLYGONM: + shp->EffectiveType = GAIA_MULTIPOLYGON; + break; + case GAIA_SHP_MULTIPOINT: + case GAIA_SHP_MULTIPOINTZ: + case GAIA_SHP_MULTIPOINTM: + shp->EffectiveType = GAIA_MULTIPOINT; + break; + } + switch (shape) + { + /* setting up a prudential dimension model */ + case GAIA_SHP_POINTZ: + case GAIA_SHP_POLYLINEZ: + case GAIA_SHP_POLYGONZ: + case GAIA_SHP_MULTIPOINTZ: + shp->EffectiveDims = GAIA_XY_Z_M; + break; + case GAIA_SHP_POINTM: + case GAIA_SHP_POLYLINEM: + case GAIA_SHP_POLYGONM: + case GAIA_SHP_MULTIPOINTM: + shp->EffectiveDims = GAIA_XY_M; + break; + default: + shp->EffectiveDims = GAIA_XY; + break; + } + shp->flShp = fl_shp; + shp->flShx = fl_shx; + shp->flDbf = fl_dbf; + shp->Dbf = dbf_list; +/* saving the SHP buffer */ + shp->BufShp = buf_shp; + shp->ShpBfsz = buf_size; +/* allocating DBF buffer */ + shp->BufDbf = malloc (sizeof (unsigned char) * dbf_reclen); + shp->DbfHdsz = dbf_size + 1; + shp->DbfReclen = dbf_reclen; + shp->Valid = 1; + shp->endian_arch = endian_arch; + return; + unsupported_conversion: +/* illegal charset */ + if (shp->LastError) + free (shp->LastError); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + return; + no_file: +/* one of shapefile's files can't be accessed */ + if (shp->LastError) + free (shp->LastError); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + if (fl_shx) + fclose (fl_shx); + if (fl_shp) + fclose (fl_shp); + if (fl_dbf) + fclose (fl_dbf); + return; + dbf_bad_magic: +/* the DBF has an invalid magin number */ + if (shp->LastError) + free (shp->LastError); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + gaiaFreeDbfList (dbf_list); + if (buf_shp) + free (buf_shp); + fclose (fl_shx); + fclose (fl_shp); + fclose (fl_dbf); + return; + error: +/* the shapefile is invalid or corrupted */ + if (shp->LastError) + free (shp->LastError); + sprintf (errMsg, "'%s' is corrupted / has invalid format", path); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + gaiaFreeDbfList (dbf_list); + if (buf_shp) + free (buf_shp); + fclose (fl_shx); + fclose (fl_shp); + fclose (fl_dbf); + return; + unsupported: +/* the shapefile has an unrecognized shape type */ + if (shp->LastError) + free (shp->LastError); + sprintf (errMsg, "'%s' shape=%d is not supported", path, shape); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + gaiaFreeDbfList (dbf_list); + if (buf_shp) + free (buf_shp); + fclose (fl_shx); + fclose (fl_shp); + if (fl_dbf) + fclose (fl_dbf); + return; + illegal_dbf: +/* the DBF-file contains unsupported data types */ + if (shp->LastError) + free (shp->LastError); + sprintf (errMsg, "'%s.dbf' contains unsupported data types", path); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + gaiaFreeDbfList (dbf_list); + if (buf_shp) + free (buf_shp); + fclose (fl_shx); + fclose (fl_shp); + if (fl_dbf) + fclose (fl_dbf); + return; +} + +static int +readShpEntity (gaiaShapefilePtr shp, int current_row, int *shplen, double *minx, + double *miny, double *maxx, double *maxy) +{ +/* trying to read an entity from shapefile */ + unsigned char buf[512]; + int len; + int rd; + int skpos; + int offset; + int off_shp; + int sz; + char errMsg[1024]; + int shape; + int endian_arch = gaiaEndianArch (); + +/* positioning and reading the SHX file */ + offset = 100 + (current_row * 8); /* 100 bytes for the header + current row displacement; each SHX row = 8 bytes */ + skpos = fseek (shp->flShx, offset, SEEK_SET); + if (skpos != 0) + goto eof; + rd = fread (buf, sizeof (unsigned char), 8, shp->flShx); + if (rd != 8) + goto eof; + off_shp = gaiaImport32 (buf, GAIA_BIG_ENDIAN, shp->endian_arch); +/* positioning and reading the DBF file */ + offset = shp->DbfHdsz + (current_row * shp->DbfReclen); + skpos = fseek (shp->flDbf, offset, SEEK_SET); + if (skpos != 0) + goto error; + rd = fread (shp->BufDbf, sizeof (unsigned char), shp->DbfReclen, + shp->flDbf); + if (rd != shp->DbfReclen) + goto error; + if (*(shp->BufDbf) == '*') + goto dbf_deleted; +/* positioning and reading corresponding SHP entity - geometry */ + offset = off_shp * 2; + skpos = fseek (shp->flShp, offset, SEEK_SET); + if (skpos != 0) + goto error; + rd = fread (buf, sizeof (unsigned char), 8, shp->flShp); + if (rd != 8) + goto error; + sz = gaiaImport32 (buf + 4, GAIA_BIG_ENDIAN, shp->endian_arch); + if ((sz * 2) > shp->ShpBfsz) + { + /* current buffer is too small; we need to allocate a bigger buffer */ + free (shp->BufShp); + shp->ShpBfsz = sz * 2; + shp->BufShp = malloc (sizeof (unsigned char) * shp->ShpBfsz); + } + /* reading the raw Geometry */ + rd = fread (shp->BufShp, sizeof (unsigned char), sz * 2, shp->flShp); + if (rd != sz * 2) + goto error; + *shplen = rd; + +/* retrieving the feature's BBOX */ + shape = gaiaImport32 (shp->BufShp + 0, GAIA_LITTLE_ENDIAN, endian_arch); + *minx = DBL_MAX; + *miny = DBL_MAX; + *maxx = DBL_MAX; + *maxy = DBL_MAX; + if (shape == GAIA_SHP_POINT || shape == GAIA_SHP_POINTZ + || shape == GAIA_SHP_POINTM) + { + *minx = + gaiaImport64 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + *maxx = *minx; + *miny = + gaiaImport64 (shp->BufShp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + *maxy = *miny; + } + if (shape == GAIA_SHP_POLYLINE || shape == GAIA_SHP_POLYLINEZ + || shape == GAIA_SHP_POLYLINEM || shape == GAIA_SHP_POLYGON + || shape == GAIA_SHP_POLYGONZ || shape == GAIA_SHP_POLYGONM + || shape == GAIA_SHP_MULTIPOINT || shape == GAIA_SHP_MULTIPOINTZ + || shape == GAIA_SHP_MULTIPOINTM) + { + *minx = + gaiaImport64 (shp->BufShp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + *miny = + gaiaImport64 (shp->BufShp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + *maxx = + gaiaImport64 (shp->BufShp + 20, GAIA_LITTLE_ENDIAN, endian_arch); + *maxy = + gaiaImport64 (shp->BufShp + 28, GAIA_LITTLE_ENDIAN, endian_arch); + } + return 1; + + eof: + if (shp->LastError) + free (shp->LastError); + shp->LastError = NULL; + return 0; + error: + if (shp->LastError) + free (shp->LastError); + sprintf (errMsg, "'%s' is corrupted / has invalid format", shp->Path); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + return 0; + dbf_deleted: + if (shp->LastError) + free (shp->LastError); + shp->LastError = NULL; + return -1; +} + +struct shp_ring_item +{ +/* a RING item [to be reassembled into a (Multi)Polygon] */ + gaiaRingPtr Ring; + int IsExterior; + gaiaRingPtr Mother; + struct shp_ring_item *Next; +}; + +struct shp_ring_collection +{ +/* a collection of RING items */ + struct shp_ring_item *First; + struct shp_ring_item *Last; +}; + +static void +shp_free_rings (struct shp_ring_collection *ringsColl) +{ +/* memory cleanup: rings collection */ + struct shp_ring_item *p; + struct shp_ring_item *pN; + p = ringsColl->First; + while (p) + { + pN = p->Next; + if (p->Ring) + gaiaFreeRing (p->Ring); + free (p); + p = pN; + } +} + +static void +shp_add_ring (struct shp_ring_collection *ringsColl, gaiaRingPtr ring) +{ +/* inserting a ring into the rings collection */ + struct shp_ring_item *p = malloc (sizeof (struct shp_ring_item)); + p->Ring = ring; + gaiaMbrRing (ring); + gaiaClockwise (ring); +/* accordingly to SHP rules interior/exterior depends on direction */ + p->IsExterior = ring->Clockwise; + p->Mother = NULL; + p->Next = NULL; +/* updating the linked list */ + if (ringsColl->First == NULL) + ringsColl->First = p; + if (ringsColl->Last != NULL) + ringsColl->Last->Next = p; + ringsColl->Last = p; +} + +static int +shp_check_rings (gaiaRingPtr exterior, gaiaRingPtr candidate) +{ +/* +/ speditively checks if the candidate could be an interior Ring +/ contained into the exterior Ring +*/ + double z; + double m; + double x0; + double y0; + double x1; + double y1; + int mid; + int ret0; + int ret1; + if (candidate->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (candidate->Coords, 0, &x0, &y0, &z); + } + else if (candidate->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (candidate->Coords, 0, &x0, &y0, &m); + } + else if (candidate->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (candidate->Coords, 0, &x0, &y0, &z, &m); + } + else + { + gaiaGetPoint (candidate->Coords, 0, &x0, &y0); + } + mid = candidate->Points / 2; + if (candidate->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (candidate->Coords, mid, &x1, &y1, &z); + } + else if (candidate->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (candidate->Coords, mid, &x1, &y1, &m); + } + else if (candidate->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (candidate->Coords, mid, &x1, &y1, &z, &m); + } + else + { + gaiaGetPoint (candidate->Coords, mid, &x1, &y1); + } + +/* testing if the first point falls on the exterior ring surface */ + ret0 = gaiaIsPointOnRingSurface (exterior, x0, y0); +/* testing if the second point falls on the exterior ring surface */ + ret1 = gaiaIsPointOnRingSurface (exterior, x1, y1); + if (ret0 || ret1) + return 1; + return 0; +} + +static int +shp_mbr_contains (gaiaRingPtr r1, gaiaRingPtr r2) +{ +/* checks if the first Ring contains the second one - MBR based */ + int ok_1 = 0; + int ok_2 = 0; + int ok_3 = 0; + int ok_4 = 0; + if (r2->MinX >= r1->MinX && r2->MinX <= r1->MaxX) + ok_1 = 1; + if (r2->MaxX >= r1->MinX && r2->MaxX <= r1->MaxX) + ok_2 = 1; + if (r2->MinY >= r1->MinY && r2->MinY <= r1->MaxY) + ok_3 = 1; + if (r2->MaxY >= r1->MinY && r2->MaxY <= r1->MaxY) + ok_4 = 1; + if (ok_1 && ok_2 && ok_3 && ok_4) + return 1; + return 0; +} + +static void +shp_arrange_rings (struct shp_ring_collection *ringsColl) +{ +/* +/ arranging Rings so to associate any interior ring +/ to the containing exterior ring +*/ + struct shp_ring_item *pInt; + struct shp_ring_item *pExt; + pExt = ringsColl->First; + while (pExt != NULL) + { + /* looping on Exterior Rings */ + if (pExt->IsExterior) + { + pInt = ringsColl->First; + while (pInt != NULL) + { + /* looping on Interior Rings */ + if (pInt->IsExterior == 0 && pInt->Mother == NULL + && shp_mbr_contains (pExt->Ring, pInt->Ring)) + { + /* ok, matches */ + if (shp_check_rings (pExt->Ring, pInt->Ring)) + pInt->Mother = pExt->Ring; + } + pInt = pInt->Next; + } + } + pExt = pExt->Next; + } + pExt = ringsColl->First; + while (pExt != NULL) + { + if (pExt->IsExterior == 0 && pExt->Mother == NULL) + { + /* orphan ring: promoting to Exterior */ + pExt->IsExterior = 1; + } + pExt = pExt->Next; + } +} + +static void +shp_build_area (struct shp_ring_collection *ringsColl, gaiaGeomCollPtr geom) +{ +/* building the final (Multi)Polygon Geometry */ + gaiaPolygonPtr polyg; + struct shp_ring_item *pExt; + struct shp_ring_item *pInt; + pExt = ringsColl->First; + while (pExt != NULL) + { + if (pExt->IsExterior) + { + /* creating a new Polygon */ + polyg = gaiaInsertPolygonInGeomColl (geom, pExt->Ring); + pInt = ringsColl->First; + while (pInt != NULL) + { + if (pExt->Ring == pInt->Mother) + { + /* adding an interior ring to current POLYGON */ + gaiaAddRingToPolyg (polyg, pInt->Ring); + /* releasing Ring ownership */ + pInt->Ring = NULL; + } + pInt = pInt->Next; + } + /* releasing Ring ownership */ + pExt->Ring = NULL; + } + pExt = pExt->Next; + } +} + +static gaiaGeomCollPtr +do_parse_geometry (const unsigned char *bufshp, int buflen, int eff_dims, + int eff_type, int *nullshape) +{ +/* attempting to parse a Geometry from the SHP */ + gaiaGeomCollPtr geom = NULL; + int shape; + double x; + double y; + double z; + double m; + int points; + int n; + int n1; + int base; + int baseZ; + int baseM; + int start; + int end; + int iv; + int ind; + int max_size; + int min_size; + int hasM; + int sz; + gaiaLinestringPtr line = NULL; + gaiaRingPtr ring = NULL; + int endian_arch = gaiaEndianArch (); + struct shp_ring_collection ringsColl; +/* initializing the RING collection */ + ringsColl.First = NULL; + ringsColl.Last = NULL; + + shape = gaiaImport32 (bufshp + 0, GAIA_LITTLE_ENDIAN, endian_arch); + if (shape == GAIA_SHP_NULL) + { + *nullshape = 1; + return NULL; + } + *nullshape = 0; + + if (shape == GAIA_SHP_POINT) + { + /* shape point */ + x = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + { + geom = gaiaAllocGeomCollXYZ (); + gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_M) + { + geom = gaiaAllocGeomCollXYM (); + gaiaAddPointToGeomCollXYM (geom, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_Z_M) + { + geom = gaiaAllocGeomCollXYZM (); + gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, 0.0); + } + else + { + geom = gaiaAllocGeomColl (); + gaiaAddPointToGeomColl (geom, x, y); + } + geom->DeclaredType = GAIA_POINT; + } + if (shape == GAIA_SHP_POINTZ) + { + /* shape point Z */ + x = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + z = gaiaImport64 (bufshp + 20, GAIA_LITTLE_ENDIAN, endian_arch); + if (buflen == 28) + m = 0.0; + else + m = gaiaImport64 (bufshp + 28, GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + { + geom = gaiaAllocGeomCollXYZ (); + gaiaAddPointToGeomCollXYZ (geom, x, y, z); + } + else if (eff_dims == GAIA_XY_M) + { + geom = gaiaAllocGeomCollXYM (); + gaiaAddPointToGeomCollXYM (geom, x, y, m); + } + else if (eff_dims == GAIA_XY_Z_M) + { + geom = gaiaAllocGeomCollXYZM (); + gaiaAddPointToGeomCollXYZM (geom, x, y, z, m); + } + else + { + geom = gaiaAllocGeomColl (); + gaiaAddPointToGeomColl (geom, x, y); + } + geom->DeclaredType = GAIA_POINT; + } + if (shape == GAIA_SHP_POINTM) + { + /* shape point M */ + x = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + m = gaiaImport64 (bufshp + 20, GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + { + geom = gaiaAllocGeomCollXYZ (); + gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_M) + { + geom = gaiaAllocGeomCollXYM (); + gaiaAddPointToGeomCollXYM (geom, x, y, m); + } + else if (eff_dims == GAIA_XY_Z_M) + { + geom = gaiaAllocGeomCollXYZM (); + gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, m); + } + else + { + geom = gaiaAllocGeomColl (); + gaiaAddPointToGeomColl (geom, x, y); + } + geom->DeclaredType = GAIA_POINT; + } + if (shape == GAIA_SHP_POLYLINE) + { + /* shape polyline */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch); + base = 44 + (n * 4); + start = 0; + for (ind = 0; ind < n; ind++) + { + if (ind < (n - 1)) + end = + gaiaImport32 (bufshp + 44 + ((ind + 1) * 4), + GAIA_LITTLE_ENDIAN, endian_arch); + else + end = n1; + points = end - start; + if (eff_dims == GAIA_XY_Z) + line = gaiaAllocLinestringXYZ (points); + else if (eff_dims == GAIA_XY_M) + line = gaiaAllocLinestringXYM (points); + else if (eff_dims == GAIA_XY_Z_M) + line = gaiaAllocLinestringXYZM (points); + else + line = gaiaAllocLinestring (points); + points = 0; + for (iv = start; iv < end; iv++) + { + x = gaiaImport64 (bufshp + base + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + base + (iv * 16) + + 8, GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + { + gaiaSetPointXYZ (line->Coords, points, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_M) + { + gaiaSetPointXYM (line->Coords, points, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_Z_M) + { + gaiaSetPointXYZM (line->Coords, points, x, y, + 0.0, 0.0); + } + else + { + gaiaSetPoint (line->Coords, points, x, y); + } + start++; + points++; + } + if (!geom) + { + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + if (eff_type == GAIA_LINESTRING) + geom->DeclaredType = GAIA_LINESTRING; + else + geom->DeclaredType = GAIA_MULTILINESTRING; + } + gaiaInsertLinestringInGeomColl (geom, line); + } + } + if (shape == GAIA_SHP_POLYLINEZ) + { + /* shape polyline Z */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch); + hasM = 0; + max_size = 38 + (2 * n) + (n1 * 16); /* size [in 16 bits words !!!] ZM */ + min_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] Z-only */ + sz = buflen / 2; + if (sz < min_size) + goto error; + if (sz == max_size) + hasM = 1; + base = 44 + (n * 4); + baseZ = base + (n1 * 16) + 16; + baseM = baseZ + (n1 * 8) + 16; + start = 0; + for (ind = 0; ind < n; ind++) + { + if (ind < (n - 1)) + end = + gaiaImport32 (bufshp + 44 + ((ind + 1) * 4), + GAIA_LITTLE_ENDIAN, endian_arch); + else + end = n1; + points = end - start; + if (eff_dims == GAIA_XY_Z) + line = gaiaAllocLinestringXYZ (points); + else if (eff_dims == GAIA_XY_M) + line = gaiaAllocLinestringXYM (points); + else if (eff_dims == GAIA_XY_Z_M) + line = gaiaAllocLinestringXYZM (points); + else + line = gaiaAllocLinestring (points); + points = 0; + for (iv = start; iv < end; iv++) + { + x = gaiaImport64 (bufshp + base + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + base + (iv * 16) + + 8, GAIA_LITTLE_ENDIAN, endian_arch); + z = gaiaImport64 (bufshp + baseZ + (iv * 8), + GAIA_LITTLE_ENDIAN, endian_arch); + if (hasM) + m = gaiaImport64 (bufshp + baseM + + (iv * 8), GAIA_LITTLE_ENDIAN, + endian_arch); + else + m = 0.0; + if (m < SHAPEFILE_NO_DATA) + m = 0.0; + if (eff_dims == GAIA_XY_Z) + { + gaiaSetPointXYZ (line->Coords, points, x, y, z); + } + else if (eff_dims == GAIA_XY_M) + { + gaiaSetPointXYM (line->Coords, points, x, y, m); + } + else if (eff_dims == GAIA_XY_Z_M) + { + gaiaSetPointXYZM (line->Coords, points, x, y, z, m); + } + else + { + gaiaSetPoint (line->Coords, points, x, y); + } + start++; + points++; + } + if (!geom) + { + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + if (eff_type == GAIA_LINESTRING) + geom->DeclaredType = GAIA_LINESTRING; + else + geom->DeclaredType = GAIA_MULTILINESTRING; + } + gaiaInsertLinestringInGeomColl (geom, line); + } + } + if (shape == GAIA_SHP_POLYLINEM) + { + /* shape polyline M */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch); + hasM = 0; + max_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] M */ + min_size = 22 + (2 * n) + (n1 * 8); /* size [in 16 bits words !!!] no-M */ + sz = buflen / 2; + if (sz < min_size) + goto error; + if (sz == max_size) + hasM = 1; + base = 44 + (n * 4); + baseM = base + (n1 * 16) + 16; + start = 0; + for (ind = 0; ind < n; ind++) + { + if (ind < (n - 1)) + end = + gaiaImport32 (bufshp + 44 + ((ind + 1) * 4), + GAIA_LITTLE_ENDIAN, endian_arch); + else + end = n1; + points = end - start; + if (eff_dims == GAIA_XY_Z) + line = gaiaAllocLinestringXYZ (points); + else if (eff_dims == GAIA_XY_M) + line = gaiaAllocLinestringXYM (points); + else if (eff_dims == GAIA_XY_Z_M) + line = gaiaAllocLinestringXYZM (points); + else + line = gaiaAllocLinestring (points); + points = 0; + for (iv = start; iv < end; iv++) + { + x = gaiaImport64 (bufshp + base + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + base + (iv * 16) + + 8, GAIA_LITTLE_ENDIAN, endian_arch); + if (hasM) + m = gaiaImport64 (bufshp + baseM + + (iv * 8), GAIA_LITTLE_ENDIAN, + endian_arch); + else + m = 0.0; + if (m < SHAPEFILE_NO_DATA) + m = 0.0; + if (eff_dims == GAIA_XY_Z) + { + gaiaSetPointXYZ (line->Coords, points, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_M) + { + gaiaSetPointXYM (line->Coords, points, x, y, m); + } + else if (eff_dims == GAIA_XY_Z_M) + { + gaiaSetPointXYZM (line->Coords, points, x, y, + 0.0, m); + } + else + { + gaiaSetPoint (line->Coords, points, x, y); + } + start++; + points++; + } + if (!geom) + { + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + if (eff_type == GAIA_LINESTRING) + geom->DeclaredType = GAIA_LINESTRING; + else + geom->DeclaredType = GAIA_MULTILINESTRING; + } + gaiaInsertLinestringInGeomColl (geom, line); + } + } + if (shape == GAIA_SHP_POLYGON) + { + /* shape polygon */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch); + base = 44 + (n * 4); + start = 0; + for (ind = 0; ind < n; ind++) + { + if (ind < (n - 1)) + end = + gaiaImport32 (bufshp + 44 + ((ind + 1) * 4), + GAIA_LITTLE_ENDIAN, endian_arch); + else + end = n1; + points = end - start; + if (eff_dims == GAIA_XY_Z) + ring = gaiaAllocRingXYZ (points); + else if (eff_dims == GAIA_XY_M) + ring = gaiaAllocRingXYM (points); + else if (eff_dims == GAIA_XY_Z_M) + ring = gaiaAllocRingXYZM (points); + else + ring = gaiaAllocRing (points); + points = 0; + for (iv = start; iv < end; iv++) + { + x = gaiaImport64 (bufshp + base + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + base + (iv * 16) + + 8, GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + { + gaiaSetPointXYZ (ring->Coords, points, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_M) + { + gaiaSetPointXYM (ring->Coords, points, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_Z_M) + { + gaiaSetPointXYZM (ring->Coords, points, x, y, + 0.0, 0.0); + } + else + { + gaiaSetPoint (ring->Coords, points, x, y); + } + start++; + points++; + } + shp_add_ring (&ringsColl, ring); + } + shp_arrange_rings (&ringsColl); + /* allocating the final geometry */ + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + if (eff_type == GAIA_POLYGON) + geom->DeclaredType = GAIA_POLYGON; + else + geom->DeclaredType = GAIA_MULTIPOLYGON; + shp_build_area (&ringsColl, geom); + } + if (shape == GAIA_SHP_POLYGONZ) + { + /* shape polygon Z */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch); + hasM = 0; + max_size = 38 + (2 * n) + (n1 * 16); /* size [in 16 bits words !!!] ZM */ + min_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] Z-only */ + sz = buflen / 2; + if (sz < min_size) + goto error; + if (sz == max_size) + hasM = 1; + base = 44 + (n * 4); + baseZ = base + (n1 * 16) + 16; + baseM = baseZ + (n1 * 8) + 16; + start = 0; + for (ind = 0; ind < n; ind++) + { + if (ind < (n - 1)) + end = + gaiaImport32 (bufshp + 44 + ((ind + 1) * 4), + GAIA_LITTLE_ENDIAN, endian_arch); + else + end = n1; + points = end - start; + if (eff_dims == GAIA_XY_Z) + ring = gaiaAllocRingXYZ (points); + else if (eff_dims == GAIA_XY_M) + ring = gaiaAllocRingXYM (points); + else if (eff_dims == GAIA_XY_Z_M) + ring = gaiaAllocRingXYZM (points); + else + ring = gaiaAllocRing (points); + points = 0; + for (iv = start; iv < end; iv++) + { + x = gaiaImport64 (bufshp + base + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + base + (iv * 16) + + 8, GAIA_LITTLE_ENDIAN, endian_arch); + z = gaiaImport64 (bufshp + baseZ + (iv * 8), + GAIA_LITTLE_ENDIAN, endian_arch); + if (hasM) + m = gaiaImport64 (bufshp + baseM + + (iv * 8), GAIA_LITTLE_ENDIAN, + endian_arch); + else + m = 0.0; + if (m < SHAPEFILE_NO_DATA) + m = 0.0; + if (eff_dims == GAIA_XY_Z) + { + gaiaSetPointXYZ (ring->Coords, points, x, y, z); + } + else if (eff_dims == GAIA_XY_M) + { + gaiaSetPointXYM (ring->Coords, points, x, y, m); + } + else if (eff_dims == GAIA_XY_Z_M) + { + gaiaSetPointXYZM (ring->Coords, points, x, y, z, m); + } + else + { + gaiaSetPoint (ring->Coords, points, x, y); + } + start++; + points++; + } + shp_add_ring (&ringsColl, ring); + } + shp_arrange_rings (&ringsColl); + /* allocating the final geometry */ + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + if (eff_type == GAIA_POLYGON) + geom->DeclaredType = GAIA_POLYGON; + else + geom->DeclaredType = GAIA_MULTIPOLYGON; + shp_build_area (&ringsColl, geom); + } + if (shape == GAIA_SHP_POLYGONM) + { + /* shape polygon M */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + n1 = gaiaImport32 (bufshp + 40, GAIA_LITTLE_ENDIAN, endian_arch); + hasM = 0; + max_size = 30 + (2 * n) + (n1 * 12); /* size [in 16 bits words !!!] M */ + min_size = 22 + (2 * n) + (n1 * 8); /* size [in 16 bits words !!!] no-M */ + sz = buflen / 2; + if (sz < min_size) + goto error; + if (sz == max_size) + hasM = 1; + base = 44 + (n * 4); + baseM = base + (n1 * 16) + 16; + start = 0; + for (ind = 0; ind < n; ind++) + { + if (ind < (n - 1)) + end = + gaiaImport32 (bufshp + 44 + ((ind + 1) * 4), + GAIA_LITTLE_ENDIAN, endian_arch); + else + end = n1; + points = end - start; + if (eff_dims == GAIA_XY_Z) + ring = gaiaAllocRingXYZ (points); + else if (eff_dims == GAIA_XY_M) + ring = gaiaAllocRingXYM (points); + else if (eff_dims == GAIA_XY_Z_M) + ring = gaiaAllocRingXYZM (points); + else + ring = gaiaAllocRing (points); + points = 0; + for (iv = start; iv < end; iv++) + { + x = gaiaImport64 (bufshp + base + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + base + (iv * 16) + + 8, GAIA_LITTLE_ENDIAN, endian_arch); + if (hasM) + m = gaiaImport64 (bufshp + baseM + + (iv * 8), GAIA_LITTLE_ENDIAN, + endian_arch); + m = 0.0; + if (m < SHAPEFILE_NO_DATA) + m = 0.0; + if (eff_dims == GAIA_XY_Z) + { + gaiaSetPointXYZ (ring->Coords, points, x, y, 0.0); + } + else if (eff_dims == GAIA_XY_M) + { + gaiaSetPointXYM (ring->Coords, points, x, y, m); + } + else if (eff_dims == GAIA_XY_Z_M) + { + gaiaSetPointXYZM (ring->Coords, points, x, y, + 0.0, m); + } + else + { + gaiaSetPoint (ring->Coords, points, x, y); + } + start++; + points++; + } + shp_add_ring (&ringsColl, ring); + } + shp_arrange_rings (&ringsColl); + /* allocating the final geometry */ + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + if (eff_type == GAIA_POLYGON) + geom->DeclaredType = GAIA_POLYGON; + else + geom->DeclaredType = GAIA_MULTIPOLYGON; + shp_build_area (&ringsColl, geom); + } + if (shape == GAIA_SHP_MULTIPOINT) + { + /* shape multipoint */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + geom->DeclaredType = GAIA_MULTIPOINT; + for (iv = 0; iv < n; iv++) + { + x = gaiaImport64 (bufshp + 40 + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + 40 + (iv * 16) + 8, + GAIA_LITTLE_ENDIAN, endian_arch); + if (eff_dims == GAIA_XY_Z) + gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0); + else if (eff_dims == GAIA_XY_M) + gaiaAddPointToGeomCollXYM (geom, x, y, 0.0); + else if (eff_dims == GAIA_XY_Z_M) + gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, 0.0); + else + gaiaAddPointToGeomColl (geom, x, y); + } + } + if (shape == GAIA_SHP_MULTIPOINTZ) + { + /* shape multipoint Z */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + hasM = 0; + max_size = 36 + (n * 16); /* size [in 16 bits words !!!] ZM */ + min_size = 28 + (n * 12); /* size [in 16 bits words !!!] Z-only */ + sz = buflen / 2; + if (sz < min_size) + goto error; + if (sz == max_size) + hasM = 1; + baseZ = 40 + (n * 16) + 16; + baseM = baseZ + (n * 8) + 16; + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + geom->DeclaredType = GAIA_MULTIPOINT; + for (iv = 0; iv < n; iv++) + { + x = gaiaImport64 (bufshp + 40 + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + 40 + (iv * 16) + 8, + GAIA_LITTLE_ENDIAN, endian_arch); + z = gaiaImport64 (bufshp + baseZ + (iv * 8), + GAIA_LITTLE_ENDIAN, endian_arch); + if (hasM) + m = gaiaImport64 (bufshp + baseM + (iv * 8), + GAIA_LITTLE_ENDIAN, endian_arch); + else + m = 0.0; + if (m < SHAPEFILE_NO_DATA) + m = 0.0; + if (eff_dims == GAIA_XY_Z) + gaiaAddPointToGeomCollXYZ (geom, x, y, z); + else if (eff_dims == GAIA_XY_M) + gaiaAddPointToGeomCollXYM (geom, x, y, m); + else if (eff_dims == GAIA_XY_Z_M) + gaiaAddPointToGeomCollXYZM (geom, x, y, z, m); + else + gaiaAddPointToGeomColl (geom, x, y); + } + } + if (shape == GAIA_SHP_MULTIPOINTM) + { + /* shape multipoint M */ + n = gaiaImport32 (bufshp + 36, GAIA_LITTLE_ENDIAN, endian_arch); + hasM = 0; + max_size = 28 + (n * 12); /* size [in 16 bits words !!!] M */ + min_size = 20 + (n * 8); /* size [in 16 bits words !!!] no-M */ + sz = buflen / 2; + if (sz < min_size) + goto error; + if (sz == max_size) + hasM = 1; + baseM = 40 + (n * 16) + 16; + if (eff_dims == GAIA_XY_Z) + geom = gaiaAllocGeomCollXYZ (); + else if (eff_dims == GAIA_XY_M) + geom = gaiaAllocGeomCollXYM (); + else if (eff_dims == GAIA_XY_Z_M) + geom = gaiaAllocGeomCollXYZM (); + else + geom = gaiaAllocGeomColl (); + geom->DeclaredType = GAIA_MULTIPOINT; + for (iv = 0; iv < n; iv++) + { + x = gaiaImport64 (bufshp + 40 + (iv * 16), + GAIA_LITTLE_ENDIAN, endian_arch); + y = gaiaImport64 (bufshp + 40 + (iv * 16) + 8, + GAIA_LITTLE_ENDIAN, endian_arch); + if (hasM) + m = gaiaImport64 (bufshp + baseM + (iv * 8), + GAIA_LITTLE_ENDIAN, endian_arch); + else + m = 0.0; + if (m < SHAPEFILE_NO_DATA) + m = 0.0; + if (eff_dims == GAIA_XY_Z) + gaiaAddPointToGeomCollXYZ (geom, x, y, 0.0); + else if (eff_dims == GAIA_XY_M) + gaiaAddPointToGeomCollXYM (geom, x, y, m); + else if (eff_dims == GAIA_XY_Z_M) + gaiaAddPointToGeomCollXYZM (geom, x, y, 0.0, m); + else + gaiaAddPointToGeomColl (geom, x, y); + } + } + + if (geom != NULL) + gaiaMbrGeometry (geom); + shp_free_rings (&ringsColl); + return geom; + + error: + fprintf (stderr, "\tcorrupted shapefile / invalid format"); + shp_free_rings (&ringsColl); + return NULL; +} + +static int +do_read_shp (const void *cache, const char *shp_path, int validate, int esri, + int *invalid) +{ +/* reading some Shapefile and testing for validity */ + int current_row; + gaiaShapefilePtr shp = NULL; + int ret; + double minx; + double miny; + double maxx; + double maxy; + double MinX = DBL_MAX; + double MinY = DBL_MAX; + double MaxX = 0.0 - DBL_MAX; + double MaxY = 0.0 - DBL_MAX; + double hMinX; + double hMinY; + double hMaxX; + double hMaxY; + int mismatching; + + *invalid = 0; + shp = allocShapefile (); + openShpRead (shp, shp_path, &hMinX, &hMinY, &hMaxX, &hMaxY, &mismatching); + if (!(shp->Valid)) + { + char extra[512]; + *extra = '\0'; + if (shp->LastError) + sprintf (extra, "\n\tcause: %s\n", shp->LastError); + fprintf (stderr, + "\terror: cannot open shapefile '%s'%s", shp_path, extra); + freeShapefile (shp); + return 0; + } + if (mismatching) + *invalid += 1; + + current_row = 0; + while (1) + { + /* reading rows from shapefile */ + int shplen; + ret = + readShpEntity (shp, current_row, &shplen, &minx, &miny, &maxx, + &maxy); + if (ret < 0) + { + /* found a DBF deleted record */ + fprintf (stderr, "\t\trow #%d: logical deletion found\n", + current_row); + current_row++; + *invalid += 1; + continue; + } + if (!ret) + { + if (!(shp->LastError)) /* normal SHP EOF */ + break; + fprintf (stderr, "\tERROR: %s\n", shp->LastError); + goto stop; + } + + if (validate) + { + int nullshape; + gaiaGeomCollPtr geom = + do_parse_geometry (shp->BufShp, shplen, shp->EffectiveDims, + shp->EffectiveType, &nullshape); + if (nullshape) + ; + else + { + if (geom == NULL) + { + fprintf (stderr, + "\t\trow #%d: unable to get a Geometry\n", + current_row); + *invalid += 1; + } + else + { + if (geom->MinX != minx || geom->MinY != miny + || geom->MaxX != maxx || geom->MaxY != maxy) + { + fprintf (stderr, + "\t\trow #%d: mismatching BBOX\n", + current_row); + *invalid += 1; + } + if (esri) + { + /* checking invalid geometries in ESRI mode */ + gaiaGeomCollPtr detail; + detail = + gaiaIsValidDetailEx_r (cache, geom, 1); + if (detail == NULL) + { + /* extra checks */ + int extra = 0; + if (gaiaIsToxic_r (cache, geom)) + extra = 1; + if (gaiaIsNotClosedGeomColl_r + (cache, geom)) + extra = 1; + if (extra) + { + char *reason = + gaiaIsValidReason_r (cache, + geom); + if (reason == NULL) + fprintf (stderr, + "\t\trow #%d: invalid Geometry (unknown reason)\n", + current_row); + else + { + fprintf (stderr, + "\t\trow #%d: %s\n", + current_row, + reason); + free (reason); + } + *invalid += 1; + } + } + else + { + char *reason = + gaiaIsValidReason_r (cache, geom); + if (reason == NULL) + fprintf (stderr, + "\t\trow #%d: invalid Geometry (unknown reason)\n", + current_row); + else + { + fprintf (stderr, + "\t\trow #%d: %s\n", + current_row, reason); + free (reason); + } + *invalid += 1; + gaiaFreeGeomColl (detail); + } + } + else + { + /* checking invalid geometries in ISO/OGC mode */ + if (gaiaIsValid_r (cache, geom) != 1) + { + char *reason = + gaiaIsValidReason_r (cache, geom); + if (reason == NULL) + fprintf (stderr, + "\t\trow #%d: invalid Geometry (unknown reason)\n", + current_row); + else + { + fprintf (stderr, + "\t\trow #%d: %s\n", + current_row, reason); + free (reason); + } + *invalid += 1; + } + } + gaiaFreeGeomColl (geom); + } + } + } + if (minx != DBL_MAX && miny != DBL_MAX && maxx != DBL_MAX + && maxy != DBL_MAX) + { + if (minx < MinX) + MinX = minx; + if (miny < MinY) + MinY = miny; + if (maxx > MaxX) + MaxX = maxx; + if (maxy > MaxY) + MaxY = maxy; + } + current_row++; + } + freeShapefile (shp); + + if (MinX != hMinX || MinY != hMinY || MaxX != hMaxX || MaxY != hMaxY) + { + fprintf (stderr, "\t\tHEADERS: found invalid BBOX\n"); + *invalid += 1; + } + + return 1; + + stop: + freeShapefile (shp); + fprintf (stderr, "\tMalformed shapefile: quitting\n"); + return 0; +} + +static void +do_clen_files (const char *out_path, const char *name) +{ +/* removing an invalid Shapefile (not properly repaired) */ + char path[1024]; + + sprintf (path, "%s/%s.shx", out_path, name); +#ifdef _WIN32 + _unlink (path); +#else + unlink (path); +#endif + + sprintf (path, "%s/%s.shp", out_path, name); +#ifdef _WIN32 + _unlink (path); +#else + unlink (path); +#endif + + sprintf (path, "%s/%s.dbf", out_path, name); +#ifdef _WIN32 + _unlink (path); +#else + unlink (path); +#endif +} + +static void +openShpWrite (gaiaShapefilePtr shp, const char *path, int shape, + gaiaDbfListPtr dbf_list) +{ +/* trying to create the shapefile */ + FILE *fl_shx = NULL; + FILE *fl_shp = NULL; + FILE *fl_dbf = NULL; + char xpath[1024]; + unsigned char *buf_shp = NULL; + int buf_size = 1024; + unsigned char *dbf_buf = NULL; + gaiaDbfFieldPtr fld; + char *sys_err; + char errMsg[1024]; + short dbf_reclen = 0; + int shp_size = 0; + int shx_size = 0; + unsigned short dbf_size = 0; + int len; + int endian_arch = gaiaEndianArch (); + char buf[2048]; + if (shp->flShp != NULL || shp->flShx != NULL || shp->flDbf != NULL) + { + sprintf (errMsg, + "attempting to reopen an already opened Shapefile\n"); + goto unsupported_conversion; + } + buf_shp = malloc (buf_size); +/* trying to open shapefile files */ + sprintf (xpath, "%s.shx", path); + fl_shx = fopen (xpath, "wb"); + if (!fl_shx) + { + sys_err = strerror (errno); + sprintf (errMsg, "unable to open '%s' for writing: %s", xpath, + sys_err); + goto no_file; + } + sprintf (xpath, "%s.shp", path); + fl_shp = fopen (xpath, "wb"); + if (!fl_shp) + { + sys_err = strerror (errno); + sprintf (errMsg, "unable to open '%s' for writing: %s", xpath, + sys_err); + goto no_file; + } + sprintf (xpath, "%s.dbf", path); + fl_dbf = fopen (xpath, "wb"); + if (!fl_dbf) + { + sys_err = strerror (errno); + sprintf (errMsg, "unable to open '%s' for writing: %s", xpath, + sys_err); + goto no_file; + } +/* allocating DBF buffer */ + dbf_reclen = 1; /* an extra byte is needed because in DBF rows first byte is a marker for deletion */ + fld = dbf_list->First; + while (fld) + { + /* computing the DBF record length */ + dbf_reclen += fld->Length; + fld = fld->Next; + } + dbf_buf = malloc (dbf_reclen); +/* writing an empty SHP file header */ + memset (buf_shp, 0, 100); + fwrite (buf_shp, 1, 100, fl_shp); + shp_size = 50; /* note: shapefile [SHP and SHX] counts sizes in WORDS of 16 bits, not in bytes of 8 bits !!!! */ +/* writing an empty SHX file header */ + memset (buf_shp, 0, 100); + fwrite (buf_shp, 1, 100, fl_shx); + shx_size = 50; +/* writing the DBF file header */ + memset (buf_shp, '\0', 32); + fwrite (buf_shp, 1, 32, fl_dbf); + dbf_size = 32; /* note: DBF counts sizes in bytes */ + fld = dbf_list->First; + while (fld) + { + /* exporting DBF Fields specifications */ + memset (buf_shp, 0, 32); + strcpy (buf, fld->Name); + memcpy (buf_shp, buf, strlen (buf)); + *(buf_shp + 11) = fld->Type; + *(buf_shp + 16) = fld->Length; + *(buf_shp + 17) = fld->Decimals; + fwrite (buf_shp, 1, 32, fl_dbf); + dbf_size += 32; + fld = fld->Next; + } + fwrite ("\r", 1, 1, fl_dbf); /* this one is a special DBF delimiter that closes file header */ + dbf_size++; +/* setting up the SHP struct */ + len = strlen (path); + shp->Path = malloc (len + 1); + strcpy (shp->Path, path); + shp->ReadOnly = 0; + shp->Shape = shape; + shp->flShp = fl_shp; + shp->flShx = fl_shx; + shp->flDbf = fl_dbf; + shp->Dbf = dbf_list; + shp->BufShp = buf_shp; + shp->ShpBfsz = buf_size; + shp->BufDbf = dbf_buf; + shp->DbfHdsz = dbf_size + 1; + shp->DbfReclen = dbf_reclen; + shp->DbfSize = dbf_size; + shp->DbfRecno = 0; + shp->ShpSize = shp_size; + shp->ShxSize = shx_size; + shp->MinX = DBL_MAX; + shp->MinY = DBL_MAX; + shp->MaxX = -DBL_MAX; + shp->MaxY = -DBL_MAX; + shp->Valid = 1; + shp->endian_arch = endian_arch; + return; + unsupported_conversion: +/* illegal charset */ + if (shp->LastError) + free (shp->LastError); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + return; + no_file: +/* one of shapefile's files can't be created/opened */ + if (shp->LastError) + free (shp->LastError); + len = strlen (errMsg); + shp->LastError = malloc (len + 1); + strcpy (shp->LastError, errMsg); + if (buf_shp) + free (buf_shp); + if (fl_shx) + fclose (fl_shx); + if (fl_shp) + fclose (fl_shp); + if (fl_dbf) + fclose (fl_dbf); + return; +} + +static int +writeShpEntity (gaiaShapefilePtr shp, const unsigned char *bufshp, int shplen, + const unsigned char *bufdbf, int dbflen) +{ +/* trying to write an entity into shapefile */ + unsigned char buf[64]; + int endian_arch = shp->endian_arch; + int shape; + double minx; + double maxx; + double miny; + double maxy; + +/* inserting entity in SHX file */ + gaiaExport32 (buf, shp->ShpSize, GAIA_BIG_ENDIAN, endian_arch); /* exports current SHP file position */ + gaiaExport32 (buf + 4, shplen / 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entitiy size [in 16 bits words !!!] */ + fwrite (buf, 1, 8, shp->flShx); + (shp->ShxSize) += 4; /* updating current SHX file position [in 16 bits words !!!] */ + +/* inserting entity in SHP file */ + gaiaExport32 (buf, shp->DbfRecno + 1, GAIA_BIG_ENDIAN, endian_arch); /* exports entity ID */ + gaiaExport32 (buf + 4, shplen / 2, GAIA_BIG_ENDIAN, endian_arch); /* exports entity size [in 16 bits words !!!] */ + fwrite (buf, 1, 8, shp->flShp); + (shp->ShpSize) += 4; + fwrite (bufshp, 1, shplen, shp->flShp); + (shp->ShpSize) += shplen / 2; /* updating current SHP file position [in 16 bits words !!!] */ + +/* inserting entity in DBF file */ + fwrite (bufdbf, 1, dbflen, shp->flDbf); + (shp->DbfRecno)++; + +/* updating the full extent BBOX */ + shape = gaiaImport32 (bufshp + 0, GAIA_LITTLE_ENDIAN, endian_arch); + if (shape == GAIA_SHP_POINT || shape == GAIA_SHP_POINTZ + || shape == GAIA_SHP_POINTM) + { + minx = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + maxx = minx; + miny = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + maxy = miny; + if (minx < shp->MinX) + shp->MinX = minx; + if (maxx > shp->MaxX) + shp->MaxX = maxx; + if (miny < shp->MinY) + shp->MinY = miny; + if (maxy > shp->MaxY) + shp->MaxY = maxy; + } + if (shape == GAIA_SHP_POLYLINE || shape == GAIA_SHP_POLYLINEZ + || shape == GAIA_SHP_POLYLINEM || shape == GAIA_SHP_POLYGON + || shape == GAIA_SHP_POLYGONZ || shape == GAIA_SHP_POLYGONM + || shape == GAIA_SHP_MULTIPOINT || shape == GAIA_SHP_MULTIPOINTZ + || shape == GAIA_SHP_MULTIPOINTM) + { + minx = gaiaImport64 (bufshp + 4, GAIA_LITTLE_ENDIAN, endian_arch); + miny = gaiaImport64 (bufshp + 12, GAIA_LITTLE_ENDIAN, endian_arch); + maxx = gaiaImport64 (bufshp + 20, GAIA_LITTLE_ENDIAN, endian_arch); + maxy = gaiaImport64 (bufshp + 28, GAIA_LITTLE_ENDIAN, endian_arch); + if (minx < shp->MinX) + shp->MinX = minx; + if (maxx > shp->MaxX) + shp->MaxX = maxx; + if (miny < shp->MinY) + shp->MinY = miny; + if (maxy > shp->MaxY) + shp->MaxY = maxy; + } + return 1; +} + +static int +check_geometry (gaiaGeomCollPtr geom, int shape) +{ +/* cheching the geometry type and dims */ + int pts = 0; + int lns = 0; + int pgs = 0; + gaiaPointPtr pt; + gaiaLinestringPtr ln; + gaiaPolygonPtr pg; + + pt = geom->FirstPoint; + while (pt != NULL) + { + pts++; + pt = pt->Next; + } + ln = geom->FirstLinestring; + while (ln != NULL) + { + lns++; + ln = ln->Next; + } + pg = geom->FirstPolygon; + while (pg != NULL) + { + pgs++; + pg = pg->Next; + } + + if (pts == 1 && lns == 0 && pgs == 0) + { + if (shape == GAIA_SHP_POINT && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_POINTZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_POINTM && geom->DimensionModel == GAIA_XY_M) + return 1; + if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_MULTIPOINTZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_MULTIPOINTM + && geom->DimensionModel == GAIA_XY_M) + return 1; + } + if (pts > 1 && lns == 0 && pgs == 0) + { + if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_MULTIPOINTZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_MULTIPOINTM + && geom->DimensionModel == GAIA_XY_M) + return 1; + } + if (pts == 0 && lns > 0 && pgs == 0) + { + if (shape == GAIA_SHP_POLYLINE && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_POLYLINEZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_POLYLINEM && geom->DimensionModel == GAIA_XY_M) + return 1; + } + if (pts == 0 && lns == 0 && pgs > 0) + { + if (shape == GAIA_SHP_POLYGON && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_POLYGONZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_POLYGONM && geom->DimensionModel == GAIA_XY_M) + return 1; + } + + return 0; +} + +static int +check_geometry_verbose (gaiaGeomCollPtr geom, int shape, char **expected, + char **actual) +{ +/* cheching the geometry type and dims - verbose */ + int pts = 0; + int lns = 0; + int pgs = 0; + gaiaPointPtr pt; + gaiaLinestringPtr ln; + gaiaPolygonPtr pg; + const char *str; + int len; + + *expected = NULL; + *actual = NULL; + pt = geom->FirstPoint; + while (pt != NULL) + { + pts++; + pt = pt->Next; + } + ln = geom->FirstLinestring; + while (ln != NULL) + { + lns++; + ln = ln->Next; + } + pg = geom->FirstPolygon; + while (pg != NULL) + { + pgs++; + pg = pg->Next; + } + + if (pts == 1 && lns == 0 && pgs == 0) + { + if (shape == GAIA_SHP_POINT && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_POINTZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_POINTM && geom->DimensionModel == GAIA_XY_M) + return 1; + if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_MULTIPOINTZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_MULTIPOINTM + && geom->DimensionModel == GAIA_XY_M) + return 1; + } + if (pts > 1 && lns == 0 && pgs == 0) + { + if (shape == GAIA_SHP_MULTIPOINT && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_MULTIPOINTZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_MULTIPOINTM + && geom->DimensionModel == GAIA_XY_M) + return 1; + } + if (pts == 0 && lns > 0 && pgs == 0) + { + if (shape == GAIA_SHP_POLYLINE && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_POLYLINEZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_POLYLINEM && geom->DimensionModel == GAIA_XY_M) + return 1; + } + if (pts == 0 && lns == 0 && pgs > 0) + { + if (shape == GAIA_SHP_POLYGON && geom->DimensionModel == GAIA_XY) + return 1; + if (shape == GAIA_SHP_POLYGONZ + && (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M)) + return 1; + if (shape == GAIA_SHP_POLYGONM && geom->DimensionModel == GAIA_XY_M) + return 1; + } + + switch (shape) + { + case GAIA_SHP_POINT: + str = "POINT"; + break; + case GAIA_SHP_POINTZ: + str = "POINT-M"; + break; + case GAIA_SHP_POINTM: + str = "POINT-Z"; + break; + case GAIA_SHP_POLYLINE: + str = "POLYLINE"; + break; + case GAIA_SHP_POLYLINEZ: + str = "POLYLINE-Z"; + break; + case GAIA_SHP_POLYLINEM: + str = "POLYLINE-M"; + break; + case GAIA_SHP_POLYGON: + str = "POLYGON"; + break; + case GAIA_SHP_POLYGONZ: + str = "POLYGON-Z"; + break; + case GAIA_SHP_POLYGONM: + str = "POLYGON-M"; + break; + case GAIA_SHP_MULTIPOINT: + str = "MULTIPOINT"; + break; + case GAIA_SHP_MULTIPOINTZ: + str = "MULTIPOINT-Z"; + break; + case GAIA_SHP_MULTIPOINTM: + str = "MULTIPOINT-M"; + break; + default: + str = "UNKNOWN"; + break; + }; + len = strlen (str); + *expected = malloc (len + 1); + strcpy (*expected, str); + + str = "UNKNOWN"; + if (pts == 1 && lns == 0 && pgs == 0) + { + if (geom->DimensionModel == GAIA_XY) + str = "POINT"; + if (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M) + str = "POINT-Z"; + if (geom->DimensionModel == GAIA_XY_M) + str = "POINT-M"; + } + if (pts > 1 && lns == 0 && pgs == 0) + { + if (geom->DimensionModel == GAIA_XY) + str = "MULTIPOINT"; + if (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M) + str = "MULTIPOINT-Z"; + if (geom->DimensionModel == GAIA_XY_M) + str = "MULTIPOINT-M"; + } + if (pts == 0 && lns > 0 && pgs == 0) + { + if (geom->DimensionModel == GAIA_XY) + str = "POLYLINE"; + if (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M) + str = "POLYLINE-Z"; + if (geom->DimensionModel == GAIA_XY_M) + str = "POLYLINE-M"; + } + if (pts == 0 && lns == 0 && pgs > 0) + { + if (geom->DimensionModel == GAIA_XY) + str = "POLYGON"; + if (geom->DimensionModel == GAIA_XY_Z + || geom->DimensionModel == GAIA_XY_Z_M) + str = "POLYGON-Z"; + return 1; + if (geom->DimensionModel == GAIA_XY_M) + str = "POLYGON-M"; + return 1; + } + len = strlen (str); + *actual = malloc (len + 1); + strcpy (*actual, str); + + return 0; +} + +static void +gaiaSaneClockwise (gaiaPolygonPtr polyg) +{ +/* +/ when exporting POLYGONs to SHAPEFILE, we must guarantee that: +/ - all EXTERIOR RING must be clockwise +/ - all INTERIOR RING must be anti-clockwise +/ +/ this function checks for the above conditions, +/ and if needed inverts the rings +*/ + int ib; + int iv; + int iv2; + double x; + double y; + double z; + double m; + gaiaRingPtr new_ring; + gaiaRingPtr ring = polyg->Exterior; + gaiaClockwise (ring); + if (!(ring->Clockwise)) + { + /* exterior ring needs inversion */ + if (ring->DimensionModel == GAIA_XY_Z) + new_ring = gaiaAllocRingXYZ (ring->Points); + else if (ring->DimensionModel == GAIA_XY_M) + new_ring = gaiaAllocRingXYM (ring->Points); + else if (ring->DimensionModel == GAIA_XY_Z_M) + new_ring = gaiaAllocRingXYZM (ring->Points); + else + new_ring = gaiaAllocRing (ring->Points); + iv2 = 0; + for (iv = ring->Points - 1; iv >= 0; iv--) + { + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + gaiaSetPointXYZ (new_ring->Coords, iv2, x, y, z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + gaiaSetPointXYM (new_ring->Coords, iv2, x, y, m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + gaiaSetPointXYZM (new_ring->Coords, iv2, x, y, z, m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + gaiaSetPoint (new_ring->Coords, iv2, x, y); + } + iv2++; + } + polyg->Exterior = new_ring; + gaiaFreeRing (ring); + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + ring = polyg->Interiors + ib; + gaiaClockwise (ring); + if (ring->Clockwise) + { + /* interior ring needs inversion */ + if (ring->DimensionModel == GAIA_XY_Z) + new_ring = gaiaAllocRingXYZ (ring->Points); + else if (ring->DimensionModel == GAIA_XY_M) + new_ring = gaiaAllocRingXYM (ring->Points); + else if (ring->DimensionModel == GAIA_XY_Z_M) + new_ring = gaiaAllocRingXYZM (ring->Points); + else + new_ring = gaiaAllocRing (ring->Points); + iv2 = 0; + for (iv = ring->Points - 1; iv >= 0; iv--) + { + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + gaiaSetPointXYZ (new_ring->Coords, iv2, x, y, z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + gaiaSetPointXYM (new_ring->Coords, iv2, x, y, m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + gaiaSetPointXYZM (new_ring->Coords, iv2, x, y, + z, m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + gaiaSetPoint (new_ring->Coords, iv2, x, y); + } + iv2++; + } + for (iv = 0; iv < ring->Points; iv++) + { + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (new_ring->Coords, iv, &x, &y, &z); + gaiaSetPointXYZ (ring->Coords, iv, x, y, z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (new_ring->Coords, iv, &x, &y, &m); + gaiaSetPointXYM (ring->Coords, iv, x, y, m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (new_ring->Coords, iv, &x, &y, + &z, &m); + gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); + } + else + { + gaiaGetPoint (new_ring->Coords, iv, &x, &y); + gaiaSetPoint (ring->Coords, iv, x, y); + } + } + gaiaFreeRing (new_ring); + } + } +} + +static int +do_export_geometry (gaiaGeomCollPtr geom, unsigned char **bufshp, int *buflen, + int xshape, int rowno, int eff_dims) +{ +/* attempting to encode a Geometry */ + unsigned char *buf; + int iv; + int tot_ln; + int tot_v; + int tot_pts; + int this_size; + int ix; + double x; + double y; + double z; + double m; + int hasM; + double minZ; + double maxZ; + double minM; + double maxM; + int endian_arch = gaiaEndianArch (); + + if (geom == NULL) + { + /* exporting a NULL Shape */ + *buflen = 4; + buf = malloc (4); + gaiaExport32 (buf + 0, GAIA_SHP_NULL, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = NULL */ + *bufshp = buf; + return 1; + } + + if (!check_geometry (geom, xshape)) + { + /* mismatching Geometry type */ + fprintf (stderr, "\tinput row #%d: mismatching Geometry type\n", + rowno); + return 0; + } + gaiaMbrGeometry (geom); + + if (xshape == GAIA_SHP_POINT) + { + /* this one is expected to be a POINT */ + gaiaPointPtr pt = geom->FirstPoint; + *buflen = 20; + buf = malloc (20); + gaiaExport32 (buf + 0, GAIA_SHP_POINT, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT */ + gaiaExport64 (buf + 4, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */ + gaiaExport64 (buf + 12, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */ + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POINTZ) + { + /* this one is expected to be a POINT Z */ + gaiaPointPtr pt = geom->FirstPoint; + *buflen = 36; + buf = malloc (36); + gaiaExport32 (buf + 0, GAIA_SHP_POINTZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT Z */ + gaiaExport64 (buf + 4, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */ + gaiaExport64 (buf + 12, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */ + gaiaExport64 (buf + 20, pt->Z, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Z coordinate */ + gaiaExport64 (buf + 28, pt->M, GAIA_LITTLE_ENDIAN, endian_arch); /* exports M coordinate */ + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POINTM) + { + /* this one is expected to be a POINT M */ + gaiaPointPtr pt = geom->FirstPoint; + *buflen = 28; + buf = malloc (28); + gaiaExport32 (buf + 0, GAIA_SHP_POINTM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POINT M */ + gaiaExport64 (buf + 4, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); /* exports X coordinate */ + gaiaExport64 (buf + 12, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports Y coordinate */ + gaiaExport64 (buf + 20, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); /* exports M coordinate */ + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POLYLINE) + { + /* this one is expected to be a LINESTRING / MULTILINESTRING */ + gaiaLinestringPtr line; + tot_ln = 0; + tot_v = 0; + line = geom->FirstLinestring; + while (line) + { + /* computes # lines and total # points */ + tot_v += line->Points; + tot_ln++; + line = line->Next; + } + this_size = 22 + (2 * tot_ln) + (tot_v * 8); /* size [in 16 bits words !!!] for this SHP entity */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_POLYLINE, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */ + gaiaExport32 (buf + 40, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + tot_v = 0; /* resets points counter */ + ix = 44; /* sets current buffer offset */ + line = geom->FirstLinestring; + while (line) + { + /* exports start point index for each line */ + gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += line->Points; + ix += 4; + line = line->Next; + } + line = geom->FirstLinestring; + while (line) + { + /* exports points for each line */ + for (iv = 0; iv < line->Points; iv++) + { + /* exports a POINT [x,y] */ + if (line->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); + } + else if (line->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); + } + else if (line->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (line->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + line = line->Next; + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POLYLINEZ) + { + /* this one is expected to be a LINESTRING / MULTILINESTRING Z */ + gaiaLinestringPtr line; + gaiaZRangeGeometry (geom, &minZ, &maxZ); + gaiaMRangeGeometry (geom, &minM, &maxM); + tot_ln = 0; + tot_v = 0; + line = geom->FirstLinestring; + while (line) + { + /* computes # lines and total # points */ + tot_v += line->Points; + tot_ln++; + line = line->Next; + } + hasM = 0; + if (eff_dims == GAIA_XY_M || eff_dims == GAIA_XY_Z_M) + hasM = 1; + if (hasM) + this_size = 38 + (2 * tot_ln) + (tot_v * 16); /* size [in 16 bits words !!!] ZM */ + else + this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] Z-only */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_POLYLINEZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE Z */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */ + gaiaExport32 (buf + 40, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + tot_v = 0; /* resets points counter */ + ix = 44; /* sets current buffer offset */ + line = geom->FirstLinestring; + while (line) + { + /* exports start point index for each line */ + gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += line->Points; + ix += 4; + line = line->Next; + } + line = geom->FirstLinestring; + while (line) + { + /* exports points for each line */ + for (iv = 0; iv < line->Points; iv++) + { + /* exports a POINT [x,y] */ + if (line->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); + } + else if (line->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); + } + else if (line->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (line->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + line = line->Next; + } + /* exporting the Z-range [min/max] */ + gaiaExport64 (buf + ix, minZ, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxZ, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + line = geom->FirstLinestring; + while (line) + { + /* exports Z-values for each line */ + for (iv = 0; iv < line->Points; iv++) + { + /* exports Z-value */ + z = 0.0; + if (line->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); + } + else if (line->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); + } + else if (line->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (line->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, z, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + line = line->Next; + } + if (hasM) + { + /* exporting the M-range [min/max] */ + gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + line = geom->FirstLinestring; + while (line) + { + /* exports M-values for each line */ + for (iv = 0; iv < line->Points; iv++) + { + /* exports M-value */ + m = 0.0; + if (line->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (line->Coords, iv, + &x, &y, &z); + } + else if (line->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (line->Coords, iv, + &x, &y, &m); + } + else if (line->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (line->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (line->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, m, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + line = line->Next; + } + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POLYLINEM) + { + /* this one is expected to be a LINESTRING / MULTILINESTRING M */ + gaiaLinestringPtr line; + gaiaMRangeGeometry (geom, &minM, &maxM); + tot_ln = 0; + tot_v = 0; + line = geom->FirstLinestring; + while (line) + { + /* computes # lines and total # points */ + tot_v += line->Points; + tot_ln++; + line = line->Next; + } + this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] for this SHP entity */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_POLYLINEM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYLINE M */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # lines in this polyline */ + gaiaExport32 (buf + 40, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + tot_v = 0; /* resets points counter */ + ix = 44; /* sets current buffer offset */ + line = geom->FirstLinestring; + while (line) + { + /* exports start point index for each line */ + gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += line->Points; + ix += 4; + line = line->Next; + } + line = geom->FirstLinestring; + while (line) + { + /* exports points for each line */ + for (iv = 0; iv < line->Points; iv++) + { + /* exports a POINT [x,y] */ + if (line->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); + } + else if (line->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); + } + else if (line->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (line->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + line = line->Next; + } + /* exporting the M-range [min/max] */ + gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + line = geom->FirstLinestring; + while (line) + { + /* exports M-values for each line */ + for (iv = 0; iv < line->Points; iv++) + { + /* exports M-value */ + m = 0.0; + if (line->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); + } + else if (line->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); + } + else if (line->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (line->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, m, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + line = line->Next; + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POLYGON) + { + /* this one is expected to be a POLYGON or a MULTIPOLYGON */ + gaiaPolygonPtr polyg; + gaiaRingPtr ring; + int ib; + tot_ln = 0; + tot_v = 0; + polyg = geom->FirstPolygon; + while (polyg) + { + /* computes # rings and total # points */ + gaiaSaneClockwise (polyg); /* we must assure that exterior ring is clockwise, and interior rings are anti-clockwise */ + ring = polyg->Exterior; /* this one is the exterior ring */ + tot_v += ring->Points; + tot_ln++; + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + tot_v += ring->Points; + tot_ln++; + } + polyg = polyg->Next; + } + this_size = 22 + (2 * tot_ln) + (tot_v * 8); /* size [in 16 bits words !!!] for this SHP entity */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_POLYGON, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */ + gaiaExport32 (buf + 40, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + tot_v = 0; /* resets points counter */ + ix = 44; /* sets current buffer offset */ + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports start point index for each line */ + ring = polyg->Exterior; /* this one is the exterior ring */ + gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += ring->Points; + ix += 4; + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + gaiaExport32 (buf + ix, tot_v, + GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += ring->Points; + ix += 4; + } + polyg = polyg->Next; + } + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports points for each ring */ + ring = polyg->Exterior; /* this one is the exterior ring */ + for (iv = 0; iv < ring->Points; iv++) + { + /* exports a POINT [x,y] - exterior ring */ + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + for (iv = 0; iv < ring->Points; iv++) + { + /* exports a POINT [x,y] - interior ring */ + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, + &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, + &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + } + polyg = polyg->Next; + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POLYGONZ) + { + /* this one is expected to be a POLYGON or a MULTIPOLYGON Z */ + gaiaPolygonPtr polyg; + gaiaRingPtr ring; + int ib; + gaiaZRangeGeometry (geom, &minZ, &maxZ); + gaiaMRangeGeometry (geom, &minM, &maxM); + tot_ln = 0; + tot_v = 0; + polyg = geom->FirstPolygon; + while (polyg) + { + /* computes # rings and total # points */ + gaiaSaneClockwise (polyg); /* we must assure that exterior ring is clockwise, and interior rings are anti-clockwise */ + ring = polyg->Exterior; /* this one is the exterior ring */ + tot_v += ring->Points; + tot_ln++; + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + tot_v += ring->Points; + tot_ln++; + } + polyg = polyg->Next; + } + hasM = 0; + if (eff_dims == GAIA_XY_M || eff_dims == GAIA_XY_Z_M) + hasM = 1; + if (hasM) + this_size = 38 + (2 * tot_ln) + (tot_v * 16); /* size [in 16 bits words !!!] ZM */ + else + this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] Z-only */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_POLYGONZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON Z */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */ + gaiaExport32 (buf + 40, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + tot_v = 0; /* resets points counter */ + ix = 44; /* sets current buffer offset */ + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports start point index for each line */ + ring = polyg->Exterior; /* this one is the exterior ring */ + gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += ring->Points; + ix += 4; + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + gaiaExport32 (buf + ix, tot_v, + GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += ring->Points; + ix += 4; + } + polyg = polyg->Next; + } + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports points for each ring */ + ring = polyg->Exterior; /* this one is the exterior ring */ + for (iv = 0; iv < ring->Points; iv++) + { + /* exports a POINT [x,y] - exterior ring */ + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + for (iv = 0; iv < ring->Points; iv++) + { + /* exports a POINT [x,y] - interior ring */ + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, + &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, + &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + } + polyg = polyg->Next; + } + /* exporting the Z-range [min/max] */ + gaiaExport64 (buf + ix, minZ, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxZ, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports Z-values for each ring */ + ring = polyg->Exterior; /* this one is the exterior ring */ + for (iv = 0; iv < ring->Points; iv++) + { + /* exports Z-values - exterior ring */ + z = 0.0; + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, z, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + for (iv = 0; iv < ring->Points; iv++) + { + /* exports Z-values - interior ring */ + z = 0.0; + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, + &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, + &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, z, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + } + polyg = polyg->Next; + } + if (hasM) + { + /* exporting the M-range [min/max] */ + gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports M-values for each ring */ + ring = polyg->Exterior; /* this one is the exterior ring */ + for (iv = 0; iv < ring->Points; iv++) + { + /* exports M-values - exterior ring */ + m = 0.0; + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, + &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, + &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, m, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + for (iv = 0; iv < ring->Points; iv++) + { + /* exports M-values - interior ring */ + m = 0.0; + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, + iv, &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, + iv, &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, + iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, m, + GAIA_LITTLE_ENDIAN, + endian_arch); + ix += 8; + } + } + polyg = polyg->Next; + } + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_POLYGONM) + { + /* this one is expected to be a POLYGON or a MULTIPOLYGON M */ + gaiaPolygonPtr polyg; + gaiaRingPtr ring; + int ib; + gaiaMRangeGeometry (geom, &minM, &maxM); + tot_ln = 0; + tot_v = 0; + polyg = geom->FirstPolygon; + while (polyg) + { + /* computes # rings and total # points */ + gaiaSaneClockwise (polyg); /* we must assure that exterior ring is clockwise, and interior rings are anti-clockwise */ + ring = polyg->Exterior; /* this one is the exterior ring */ + tot_v += ring->Points; + tot_ln++; + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + tot_v += ring->Points; + tot_ln++; + } + polyg = polyg->Next; + } + this_size = 30 + (2 * tot_ln) + (tot_v * 12); /* size [in 16 bits words !!!] for this SHP entity */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_POLYGONM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = POLYGON M */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_ln, GAIA_LITTLE_ENDIAN, endian_arch); /* exports # rings in this polygon */ + gaiaExport32 (buf + 40, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + tot_v = 0; /* resets points counter */ + ix = 44; /* sets current buffer offset */ + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports start point index for each line */ + ring = polyg->Exterior; /* this one is the exterior ring */ + gaiaExport32 (buf + ix, tot_v, GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += ring->Points; + ix += 4; + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + gaiaExport32 (buf + ix, tot_v, + GAIA_LITTLE_ENDIAN, endian_arch); + tot_v += ring->Points; + ix += 4; + } + polyg = polyg->Next; + } + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports points for each ring */ + ring = polyg->Exterior; /* this one is the exterior ring */ + for (iv = 0; iv < ring->Points; iv++) + { + /* exports a POINT [x,y] - exterior ring */ + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + for (iv = 0; iv < ring->Points; iv++) + { + /* exports a POINT [x,y] - interior ring */ + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, + &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, + &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, x, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, y, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + } + polyg = polyg->Next; + } + /* exporting the M-range [min/max] */ + gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + polyg = geom->FirstPolygon; + while (polyg) + { + /* exports M-values for each ring */ + ring = polyg->Exterior; /* this one is the exterior ring */ + for (iv = 0; iv < ring->Points; iv++) + { + /* exports M-values - exterior ring */ + m = 0.0; + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, m, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + for (ib = 0; ib < polyg->NumInteriors; ib++) + { + /* that ones are the interior rings */ + ring = polyg->Interiors + ib; + for (iv = 0; iv < ring->Points; iv++) + { + /* exports M-values - interior ring */ + m = 0.0; + if (ring->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ (ring->Coords, iv, + &x, &y, &z); + } + else if (ring->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM (ring->Coords, iv, + &x, &y, &m); + } + else if (ring->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM (ring->Coords, iv, + &x, &y, &z, &m); + } + else + { + gaiaGetPoint (ring->Coords, iv, &x, &y); + } + gaiaExport64 (buf + ix, m, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + } + } + polyg = polyg->Next; + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_MULTIPOINT) + { + /* this one is expected to be a MULTIPOINT */ + gaiaPointPtr pt; + tot_pts = 0; + pt = geom->FirstPoint; + while (pt) + { + /* computes # points */ + tot_pts++; + pt = pt->Next; + } + this_size = 20 + (tot_pts * 8); /* size [in 16 bits words !!!] for this SHP entity */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_MULTIPOINT, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + ix = 40; /* sets current buffer offset */ + pt = geom->FirstPoint; + while (pt) + { + /* exports each point */ + gaiaExport64 (buf + ix, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = pt->Next; + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_MULTIPOINTZ) + { + /* this one is expected to be a MULTIPOINT Z */ + gaiaPointPtr pt; + gaiaZRangeGeometry (geom, &minZ, &maxZ); + gaiaMRangeGeometry (geom, &minM, &maxM); + tot_pts = 0; + pt = geom->FirstPoint; + while (pt) + { + /* computes # points */ + tot_pts++; + pt = pt->Next; + } + hasM = 0; + if (eff_dims == GAIA_XY_M || eff_dims == GAIA_XY_Z_M) + hasM = 1; + if (hasM) + this_size = 36 + (tot_pts * 16); /* size [in 16 bits words !!!] ZM */ + else + this_size = 28 + (tot_pts * 12); /* size [in 16 bits words !!!] Z-only */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_MULTIPOINTZ, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT Z */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + ix = 40; /* sets current buffer offset */ + pt = geom->FirstPoint; + while (pt) + { + /* exports each point */ + gaiaExport64 (buf + ix, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = pt->Next; + } + /* exporting the Z-range [min/max] */ + gaiaExport64 (buf + ix, minZ, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxZ, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = geom->FirstPoint; + while (pt) + { + /* exports Z-values */ + gaiaExport64 (buf + ix, pt->Z, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = pt->Next; + } + if (hasM) + { + /* exporting the M-range [min/max] */ + gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = geom->FirstPoint; + while (pt) + { + /* exports M-values */ + gaiaExport64 (buf + ix, pt->M, + GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = pt->Next; + } + } + *bufshp = buf; + return 1; + } + if (xshape == GAIA_SHP_MULTIPOINTM) + { + /* this one is expected to be a MULTIPOINT M */ + gaiaPointPtr pt; + gaiaMRangeGeometry (geom, &minM, &maxM); + tot_pts = 0; + pt = geom->FirstPoint; + while (pt) + { + /* computes # points */ + tot_pts++; + pt = pt->Next; + } + this_size = 28 + (tot_pts * 12); /* size [in 16 bits words !!!] for this SHP entity */ + *buflen = this_size * 2; + buf = malloc (this_size * 2); + gaiaExport32 (buf + 0, GAIA_SHP_MULTIPOINTM, GAIA_LITTLE_ENDIAN, endian_arch); /* exports geometry type = MULTIPOINT M */ + gaiaExport64 (buf + 4, geom->MinX, GAIA_LITTLE_ENDIAN, endian_arch); /* exports the MBR for this geometry */ + gaiaExport64 (buf + 12, geom->MinY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 20, geom->MaxX, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport64 (buf + 28, geom->MaxY, GAIA_LITTLE_ENDIAN, endian_arch); + gaiaExport32 (buf + 36, tot_pts, GAIA_LITTLE_ENDIAN, endian_arch); /* exports total # points */ + ix = 40; /* sets current buffer offset */ + pt = geom->FirstPoint; + while (pt) + { + /* exports each point */ + gaiaExport64 (buf + ix, pt->X, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, pt->Y, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = pt->Next; + } + /* exporting the M-range [min/max] */ + gaiaExport64 (buf + ix, minM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + gaiaExport64 (buf + ix, maxM, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = geom->FirstPoint; + while (pt) + { + /* exports M-values */ + gaiaExport64 (buf + ix, pt->M, GAIA_LITTLE_ENDIAN, endian_arch); + ix += 8; + pt = pt->Next; + } + *bufshp = buf; + return 1; + } + + fprintf (stderr, + "\tinput row #%d: unable to export a consistent Geometry\n", + rowno); + return 0; +} + +static int +do_repair_shapefile (const void *cache, const char *shp_path, + const char *out_path, int validate, int esri, int force, + int *repair_failed) +{ +/* repairing some Shapefile */ + int current_row; + gaiaShapefilePtr shp_in = NULL; + gaiaShapefilePtr shp_out = NULL; + int ret; + gaiaDbfListPtr dbf_list = NULL; + gaiaDbfFieldPtr in_fld; + double minx; + double miny; + double maxx; + double maxy; + double hMinX; + double hMinY; + double hMaxX; + double hMaxY; + int mismatching; + + *repair_failed = 0; + +/* opening the INPUT SHP */ + shp_in = allocShapefile (); + openShpRead (shp_in, shp_path, &hMinX, &hMinY, &hMaxX, &hMaxY, + &mismatching); + if (!(shp_in->Valid)) + { + char extra[512]; + *extra = '\0'; + if (shp_in->LastError) + sprintf (extra, "\n\t\tcause: %s\n", shp_in->LastError); + fprintf (stderr, + "\t\terror: cannot open shapefile '%s'%s", shp_path, extra); + freeShapefile (shp_in); + return 0; + } + +/* preparing the DBF fields list - OUTPUT */ + dbf_list = gaiaAllocDbfList (); + in_fld = shp_in->Dbf->First; + while (in_fld) + { + /* adding a DBF field - OUTPUT */ + gaiaAddDbfField (dbf_list, in_fld->Name, in_fld->Type, in_fld->Offset, + in_fld->Length, in_fld->Decimals); + in_fld = in_fld->Next; + } + +/* creating the OUTPUT SHP */ + shp_out = allocShapefile (); + openShpWrite (shp_out, out_path, shp_in->Shape, dbf_list); + if (!(shp_out->Valid)) + { + char extra[512]; + *extra = '\0'; + if (shp_out->LastError) + sprintf (extra, "\n\t\tcause: %s\n", shp_out->LastError); + fprintf (stderr, + "\t\terror: cannot open shapefile '%s'%s", out_path, extra); + freeShapefile (shp_in); + freeShapefile (shp_out); + gaiaFreeDbfList (dbf_list); + return 0; + } + + current_row = 0; + while (1) + { + /* reading rows from shapefile */ + int shplen; + ret = + readShpEntity (shp_in, current_row, &shplen, &minx, &miny, &maxx, + &maxy); + if (ret < 0) + { + /* found a DBF deleted record */ + current_row++; + continue; + } + if (!ret) + { + if (!(shp_in->LastError)) /* normal SHP EOF */ + break; + fprintf (stderr, "\t\tERROR: %s\n", shp_in->LastError); + goto stop; + } + if (validate || force) + { + /* attempting to rearrange geometries */ + unsigned char *bufshp; + int buflen; + int nullshape; + gaiaGeomCollPtr geom = + do_parse_geometry (shp_in->BufShp, shplen, + shp_in->EffectiveDims, + shp_in->EffectiveType, &nullshape); + if (nullshape) + goto default_null; + if (geom == NULL) + { + fprintf (stderr, + "\t\tinput row #%d: unexpected NULL geometry\n", + current_row); + *repair_failed = 1; + goto default_null; + } + + if (validate) + { + /* testing for invalid Geometries */ + int is_invalid = 0; + if (esri) + { + /* checking invalid geometries in ESRI mode */ + gaiaGeomCollPtr detail; + detail = gaiaIsValidDetailEx_r (cache, geom, 1); + if (detail == NULL) + { + /* extra checks */ + int extra = 0; + if (gaiaIsToxic_r (cache, geom)) + extra = 1; + if (gaiaIsNotClosedGeomColl_r (cache, geom)) + extra = 1; + if (extra) + is_invalid = 1; + } + else + { + is_invalid = 1; + gaiaFreeGeomColl (detail); + } + } + else + { + /* checking invalid geometries in ISO/OGC mode */ + if (gaiaIsValid_r (cache, geom) != 1) + is_invalid = 1; + } + +#ifdef ENABLE_RTTOPO /* only if RTTOPO is enabled */ + if (is_invalid) + { + /* attempting to repair an invalid Geometry */ + char *expected; + char *actual; + gaiaGeomCollPtr discarded; + gaiaGeomCollPtr result = + gaiaMakeValid (cache, geom); + if (result == NULL) + { + fprintf (stderr, + "\t\tinput row #%d: unexpected MakeValid failure\n", + current_row); + gaiaFreeGeomColl (geom); + *repair_failed = 1; + goto default_null; + } + discarded = gaiaMakeValidDiscarded (cache, geom); + if (discarded != NULL) + { + fprintf (stderr, + "\t\tinput row #%d: MakeValid reports discarded elements\n", + current_row); + gaiaFreeGeomColl (result); + gaiaFreeGeomColl (discarded); + gaiaFreeGeomColl (geom); + *repair_failed = 1; + goto default_null; + } + if (!check_geometry_verbose + (result, shp_in->Shape, &expected, &actual)) + { + fprintf (stderr, + "\t\tinput row #%d: MakeValid returned an invalid SHAPE (expected %s, got %s)\n", + current_row, expected, actual); + free (expected); + free (actual); + gaiaFreeGeomColl (result); + gaiaFreeGeomColl (geom); + *repair_failed = 1; + goto default_null; + } + gaiaFreeGeomColl (geom); + geom = result; + } +#endif /* end RTTOPO conditional */ + + if (!do_export_geometry + (geom, &bufshp, &buflen, shp_in->Shape, + current_row, shp_out->EffectiveDims)) + { + gaiaFreeGeomColl (geom); + goto stop; + } + gaiaFreeGeomColl (geom); + } + else + { + if (!do_export_geometry + (geom, &bufshp, &buflen, shp_in->Shape, + current_row, shp_out->EffectiveDims)) + { + gaiaFreeGeomColl (geom); + goto stop; + } + gaiaFreeGeomColl (geom); + } + goto ok_geom; + + default_null: + /* exporting a NULL shape */ + do_export_geometry + (NULL, &bufshp, &buflen, shp_in->Shape, + current_row, shp_out->EffectiveDims); + + ok_geom: + ret = writeShpEntity + (shp_out, bufshp, buflen, shp_in->BufDbf, + shp_in->DbfReclen); + free (bufshp); + if (!ret) + goto stop; + } + else + { + /* passing geometries exactly as they were */ + if (!writeShpEntity + (shp_out, shp_in->BufShp, shplen, shp_in->BufDbf, + shp_in->DbfReclen)) + goto stop; + } + current_row++; + } + gaiaFlushShpHeaders (shp_out); + freeShapefile (shp_in); + freeShapefile (shp_out); + return 1; + + stop: + freeShapefile (shp_in); + freeShapefile (shp_out); + fprintf (stderr, + "\t\tMalformed shapefile, impossible to repair: quitting\n"); + return 0; +} + +static int +do_test_shapefile (const void *cache, const char *shp_path, int validate, + int esri, int *invalid) +{ +/* testing a Shapefile for validity */ + int n_invalid; + + fprintf (stderr, "\nVerifying %s.shp\n", shp_path); + *invalid = 0; + if (!do_read_shp (cache, shp_path, validate, esri, &n_invalid)) + return 0; + if (n_invalid) + { + fprintf (stderr, "\tfound %d invalidit%s: cleaning required.\n", + n_invalid, (n_invalid > 1) ? "ies" : "y"); + *invalid = 1; + } + else + fprintf (stderr, "\tfound to be already valid.\n"); + return 1; +} + +static int +check_extension (const char *file_name) +{ +/* checks the file extension */ + const char *mark = NULL; + int len = strlen (file_name); + const char *p = file_name + len - 1; + + while (p >= file_name) + { + if (*p == '.') + mark = p; + p--; + } + if (mark == NULL) + return SUFFIX_DISCARD; + if (strcasecmp (mark, ".shp") == 0) + return SUFFIX_SHP; + if (strcasecmp (mark, ".shx") == 0) + return SUFFIX_SHX; + if (strcasecmp (mark, ".dbf") == 0) + return SUFFIX_DBF; + return SUFFIX_DISCARD; +} + +static int +do_scan_dir (const void *cache, const char *in_dir, const char *out_dir, + int *n_shp, int *r_shp, int *x_shp, int validate, int esri, + int force) +{ +/* scanning a directory and searching for Shapefiles to be checked */ + struct shp_entry *p_shp; + struct shp_list *list = alloc_shp_list (); + +#if defined(_WIN32) && !defined(__MINGW32__) +/* Visual Studio .NET */ + struct _finddata_t c_file; + intptr_t hFile; + char *path; + char *name; + int len; + int ret; + if (_chdir (in_dir) < 0) + goto error; + if ((hFile = _findfirst ("*.shp", &c_file)) == -1L) + ; + else + { + while (1) + { + if ((c_file.attrib & _A_RDONLY) == _A_RDONLY + || (c_file.attrib & _A_NORMAL) == _A_NORMAL) + { + name = sqlite3_mprintf ("%s", c_file.name); + len = strlen (name); + name[len - 4] = '\0'; + path = sqlite3_mprintf ("%s/%s", in_dir, name); + do_add_shapefile (list, path, name, SUFFIX_SHP); + } + if (_findnext (hFile, &c_file) != 0) + break; + } + _findclose (hFile); + if ((hFile = _findfirst ("*.shx", &c_file)) == -1L) + ; + else + { + while (1) + { + if ((c_file.attrib & _A_RDONLY) == _A_RDONLY + || (c_file.attrib & _A_NORMAL) == _A_NORMAL) + { + name = sqlite3_mprintf ("%s", c_file.name); + len = strlen (name); + name[len - 4] = '\0'; + path = sqlite3_mprintf ("%s/%s", in_dir, name); + do_add_shapefile (list, path, name, SUFFIX_SHX); + } + if (_findnext (hFile, &c_file) != 0) + break; + } + _findclose (hFile); + if ((hFile = _findfirst ("*.dbf", &c_file)) == -1L) + ; + else + { + while (1) + { + if ((c_file.attrib & _A_RDONLY) == _A_RDONLY + || (c_file.attrib & _A_NORMAL) == _A_NORMAL) + { + name = sqlite3_mprintf ("%s", c_file.name); + len = strlen (name); + name[len - 4] = '\0'; + path = + sqlite3_mprintf ("%s/%s", in_dir, name); + do_add_shapefile (list, path, name, + SUFFIX_DBF); + } + if (_findnext (hFile, &c_file) != 0) + break; + } + _findclose (hFile); + } + } + } +#else +/* not Visual Studio .NET */ + char *path; + char *name; + struct dirent *entry; + int len; + int suffix; + DIR *dir = opendir (in_dir); + if (!dir) + goto error; + while (1) + { + /* extracting the SHP candidates */ + entry = readdir (dir); + if (!entry) + break; + suffix = check_extension (entry->d_name); + if (suffix == SUFFIX_DISCARD) + continue; + path = sqlite3_mprintf ("%s/%s", in_dir, entry->d_name); + len = strlen (path); + path[len - 4] = '\0'; + name = sqlite3_mprintf ("%s", entry->d_name); + len = strlen (name); + name[len - 4] = '\0'; + do_add_shapefile (list, path, name, suffix); + } + closedir (dir); +#endif + + p_shp = list->first; + while (p_shp != NULL) + { + if (test_valid_shp (p_shp)) + { + int invalid; + if (!do_test_shapefile + (cache, p_shp->base_name, validate, esri, &invalid)) + goto error; + *n_shp += 1; + if (invalid) + *x_shp += 1; + if ((invalid || force) && out_dir != NULL) + { + /* attempting to repair */ + int repair_failed; + int ret; + char *out_path = sqlite3_mprintf ("%s/%s", out_dir, + p_shp->file_name); + fprintf (stderr, "\tAttempting to repair: %s.shp\n", + out_path); + ret = + do_repair_shapefile (cache, p_shp->base_name, + out_path, validate, esri, force, + &repair_failed); + sqlite3_free (out_path); + if (!ret) + goto error; + if (repair_failed) + { + do_clen_files (out_dir, p_shp->base_name); + fprintf (stderr, + "\tFAILURE: automatic repair is impossible, manual repair required.\n"); + } + else + { + *r_shp += 1; + fprintf (stderr, "\tOK, successfully repaired.\n"); + } + } + } + p_shp = p_shp->next; + } + + free_shp_list (list); + return 1; + + error: + free_shp_list (list); + fprintf (stderr, "Unable to access \"%s\"\n", in_dir); + return 0; +} + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "shp_sanitize : %s\n", VERSION); + fprintf (stderr, "target CPU ..: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ..: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} + +static void +do_help () +{ +/* printing the argument list */ + fprintf (stderr, "\n\nusage: shp_sanitize ARGLIST\n"); + fprintf (stderr, + "=================================================================\n"); + fprintf (stderr, + "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); + fprintf (stderr, + "-idir or --in-dir dir-path directory expected to contain\n" + " all SHP to be checked\n"); + fprintf (stderr, + "-odir or --out-dir dir-path directory where to\n" + " store all repaired SHPs\n\n"); + fprintf (stderr, + "======================= optional args ===========================\n" + "-geom or --invalid-geoms checks for invalid Geometries\n" + "-esri or --esri-flag tolerates ESRI-like inner holes\n" + "-force or --force-repair unconditionally repair\n\n"); +} + +int +main (int argc, char *argv[]) +{ +/* the MAIN function simply perform arguments checking */ + int i; + int error = 0; + int next_arg = ARG_NONE; + char *in_dir = NULL; + char *out_dir = NULL; + int validate = 0; + int esri = 0; + int force = 0; + int n_shp = 0; + int r_shp = 0; + int x_shp = 0; + const void *cache; + + for (i = 1; i < argc; i++) + { + /* parsing the invocation arguments */ + if (next_arg != ARG_NONE) + { + switch (next_arg) + { + case ARG_IN_DIR: + in_dir = argv[i]; + break; + case ARG_OUT_DIR: + out_dir = argv[i]; + break; + }; + next_arg = ARG_NONE; + continue; + } + if (strcasecmp (argv[i], "--help") == 0 + || strcmp (argv[i], "-h") == 0) + { + do_help (); + return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; + } + if (strcasecmp (argv[i], "-idir") == 0 + || strcasecmp (argv[i], "--in-dir") == 0) + { + next_arg = ARG_IN_DIR; + continue; + } + if (strcasecmp (argv[i], "-odir") == 0 + || strcasecmp (argv[i], "--out-dir") == 0) + { + next_arg = ARG_OUT_DIR; + continue; + } + if (strcasecmp (argv[i], "-geom") == 0 + || strcasecmp (argv[i], "--invalid-geoms") == 0) + { + validate = 1; + continue; + } + if (strcasecmp (argv[i], "-esri") == 0 + || strcasecmp (argv[i], "--esri-flag") == 0) + { + esri = 1; + continue; + } + if (strcasecmp (argv[i], "-force") == 0 + || strcasecmp (argv[i], "--force-repair") == 0) + { + force = 1; + continue; + } + fprintf (stderr, "unknown argument: %s\n", argv[i]); + error = 1; + } + if (error) + { + do_help (); + return -1; + } +/* checking the arguments */ + if (!in_dir) + { + fprintf (stderr, "did you forget setting the --in-dir argument ?\n"); + error = 1; + } + if (error) + { + do_help (); + return -1; + } + +#ifndef ENABLE_RTTOPO /* only if RTTOPO is disabled */ + if (validate) + { + validate = 0; + fprintf (stderr, + "the --validate-geoms option will be ignored because\n" + "this copy of \"shp_sanitize\" was built by disabling RTTOPO support.\n\n"); + } +#endif /* end RTTOPO conditional */ + + if (out_dir != NULL) + { +#ifdef _WIN32 + if (_mkdir (out_dir) != 0) +#else + if (mkdir (out_dir, 0777) != 0) +#endif + { + fprintf (stderr, + "ERROR: unable to create the output directory\n%s\n%s\n\n", + out_dir, strerror (errno)); + return -1; + } + } + + cache = spatialite_alloc_connection (); + spatialite_set_silent_mode (cache); + fprintf (stderr, "\nInput dir: %s\n", in_dir); + if (out_dir != NULL) + { + fprintf (stderr, "Output dir: %s\n", out_dir); + if (force) + fprintf (stderr, "Unconditionally repairing all Shapefiles\n"); + } + else + fprintf (stderr, "Only a diagnostic report will be reported\n"); + if (validate) + { + fprintf (stderr, "Checking for invalid geometries (%s mode)\n", + esri ? "ESRI" : "ISO/OGC"); + } + + if (!do_scan_dir + (cache, in_dir, out_dir, &n_shp, &r_shp, &x_shp, validate, esri, force)) + { + fprintf (stderr, + "\n... quitting ... some unexpected error occurred\n"); + spatialite_cleanup_ex (cache); + return -1; + } + + fprintf (stderr, "\n===========================================\n"); + fprintf (stderr, "%d Shapefil%s ha%s been inspected.\n", n_shp, + (n_shp > 1) ? "es" : "e", (n_shp > 1) ? "ve" : "s"); + fprintf (stderr, "%d malformed Shapefil%s ha%s been identified.\n", x_shp, + (x_shp > 1) ? "es" : "e", (x_shp > 1) ? "ve" : "s"); + fprintf (stderr, "%d Shapefil%s ha%s been repaired.\n\n", r_shp, + (r_shp > 1) ? "es" : "e", (r_shp > 1) ? "ve" : "s"); + + spatialite_cleanup_ex (cache); + return 0; +} Index: spatialite_convert.c ================================================================== --- spatialite_convert.c +++ spatialite_convert.c @@ -31,11 +31,15 @@ #include #include #include +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else #include "config.h" +#endif #ifdef SPATIALITE_AMALGAMATION #include #else #include @@ -6872,10 +6876,23 @@ } spatialite_init_ex (db_handle, cache, 0); *handle = db_handle; return; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_convert: %s\n", VERSION); + fprintf (stderr, "target CPU .......: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite ....: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 .......: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -6882,14 +6899,15 @@ fprintf (stderr, "\n\nusage: spatialite_convert ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite DB path\n\n"); fprintf (stderr, - "-v or --version num target Version (2, 3, 4)\n"); + "-tv or --target-version num target Version (2, 3, 4)\n"); } int main (int argc, char *argv[]) { @@ -6926,10 +6944,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-d") == 0) { next_arg = ARG_DB_PATH; continue; @@ -6937,12 +6961,12 @@ if (strcasecmp (argv[i], "--db-path") == 0) { next_arg = ARG_DB_PATH; continue; } - if (strcasecmp (argv[i], "--version") == 0 - || strcmp (argv[i], "-v") == 0) + if (strcasecmp (argv[i], "--target-version") == 0 + || strcmp (argv[i], "-tv") == 0) { next_arg = ARG_VERSION; continue; } fprintf (stderr, "unknown argument: %s\n", argv[i]); ADDED spatialite_dem.c Index: spatialite_dem.c ================================================================== --- spatialite_dem.c +++ spatialite_dem.c @@ -0,0 +1,3635 @@ +/* +/ spatialite_dem +/ +/ a tool for setting Z coordinates from XYZ files +/ +/ version 1.0, 2017-09-14 +/ +/ Author: Mark Johnson, Berlin Germany mj10777@googlemail.com +/ +/ Copyright (C) 2017 Alessandro Furieri +/ +/ This program is free software: you can redistribute it and/or modify +/ it under the terms of the GNU General Public License as published by +/ the Free Software Foundation, either version 3 of the License, or +/ (at your option) any later version. +/ +/ This program is distributed in the hope that it will be useful, +/ but WITHOUT ANY WARRANTY; without even the implied warranty of +/ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/ GNU General Public License for more details. +/ +/ You should have received a copy of the GNU General Public License +/ along with this program. If not, see . +/ +*/ +// -- -- ---------------------------------- -- +// astyle spatialite_dem.c +// valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all --log-file=valgrind.spatialite_dem.utm_fetchz.txt ./spatialite_dem -fetchz_xy 24747.115253 20725.147344 +// -- -- ---------------------------------- -- +#if defined(_WIN32) && !defined(__MINGW32__) +/* MSVC strictly requires this include [off_t] */ +#include +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#include +#include +#else +#include "config.h" +#include +#endif + +#ifdef SPATIALITE_AMALGAMATION +#include +#else +#include +#endif + +#include +#include +#include + +#ifdef _WIN32 +#define strcasecmp _stricmp +#endif /* not WIN32 */ +// -- -- ---------------------------------- -- +#define ARG_NONE 0 +#define ARG_DB_PATH 1 +#define ARG_TABLE 2 +#define ARG_COL 3 +#define ARG_DEM_PATH 4 +#define ARG_TABLE_DEM 5 +#define ARG_COL_DEM 6 +#define ARG_RESOLUTION_DEM 7 +#define ARG_COPY_M 8 +#define ARG_COMMAND_TYPE 9 +#define ARG_FETCHZ_X 10 +#define ARG_FETCHZ_Y 11 +#define ARG_FETCHZ_XY 12 +#define ARG_DEFAULT_SRID 13 +// -- -- ---------------------------------- -- +#define CMD_DEM_SNIFF 100 +#define CMD_DEM_FETCHZ 101 +#define CMD_DEM_CREATE 102 +#define CMD_DEM_IMPORT_XYZ 103 +#define CMD_DEM_UPDATEZ 104 +// -- -- ---------------------------------- -- +#define CONF_TYPE_DEM 1 +#define CONF_TYPE_SOURCE 2 +// -- -- ---------------------------------- -- +// Definitions used for dem-conf +// -- -- ---------------------------------- -- +#define MAXBUF 1024 +#define DELIM "=" +#ifdef _WIN32 +#define LENGTHNL 2 +#else +#define LENGTHNL 1 +#endif /* not WIN32 */ +// -- -- ---------------------------------- -- +// Output of time elapse +// min = (int)(time_diff.tv_sec/60); +// secs = (int)(time_diff.tv_sec-(min*60)); +// msecs = (int)(time_diff.tv_usec/1000); +// printf("%d mins %02d.%03d secs",min,sec,msecs); +// -- -- ---------------------------------- -- +int timeval_subtract (struct timeval *time_diff, struct timeval *time_end, struct timeval *time_start, char **time_message) +{ + int diff=0; + int days=0; + int hours=0; + int mins=0; + int secs=0; + int msecs=0; +// Perform the carry for the later subtraction by updating time_start. + if (time_end->tv_usec < time_start->tv_usec) + { + int nsec = (time_start->tv_usec - time_end->tv_usec) / 1000000 + 1; + time_start->tv_usec -= 1000000 * nsec; + time_start->tv_sec += nsec; + } + if (time_end->tv_usec - time_start->tv_usec > 1000000) + { + int nsec = (time_end->tv_usec - time_start->tv_usec) / 1000000; + time_start->tv_usec += 1000000 * nsec; + time_start->tv_sec -= nsec; + } +// Compute the time remaining to wait. tv_usec is certainly positive. + time_diff->tv_sec = time_end->tv_sec - time_start->tv_sec; + time_diff->tv_usec = time_end->tv_usec - time_start->tv_usec; +// -- -- ---------------------------------- -- + diff = (int)time_diff->tv_sec; + if (diff > 86400 ) + {// sec per day + days = diff / 86400; + diff = diff-(days*86400); + } + if (diff > 3660 ) + {// sec per hour + hours = diff / 3660; + diff = diff -(hours*3660); + } + if (diff > 60 ) + { + mins = diff / 60; + } + secs = diff - (mins * 60); + msecs = (int)(time_diff->tv_usec/1000); +// -- -- ---------------------------------- -- + if (*time_message) + { + sqlite3_free(*time_message); + *time_message = NULL; + } + if ( days > 0) + { + *time_message = sqlite3_mprintf(">> time needed: %2 days %02d hours %02d mins %02d secs %02d milli-secs", days, hours, mins, secs,msecs); + } else if ( hours > 0) + { + *time_message = sqlite3_mprintf(">> time needed: %02d hours %02d mins %02d secs %02d milli-secs", hours, mins, secs,msecs); + } else if ( mins > 0) + { + *time_message = sqlite3_mprintf(">> time needed: %02d mins %02d secs %02d milli-secs", mins, secs,msecs); + } + else if (secs > 0 ) + { + *time_message = sqlite3_mprintf(">> time needed: %02d secs %02d milli-secs", secs,msecs); + } + else + { + *time_message = sqlite3_mprintf(">> time needed: %02d milli-secs",msecs); + } +// -- -- ---------------------------------- -- +// Return 1 if time_diff is negative. + return time_end->tv_sec < time_start->tv_sec; +// -- -- ---------------------------------- -- +} +// -- -- ---------------------------------- -- +// dem-conf structure +// -- -- ---------------------------------- -- +struct config_dem +{ + char dem_path[MAXBUF]; + char dem_table[MAXBUF]; + char dem_geometry[MAXBUF]; + double dem_extent_minx; + double dem_extent_miny; + double dem_extent_maxx; + double dem_extent_maxy; + double dem_resolution; + int dem_srid; + unsigned int dem_rows_count; + int default_srid; +// Not to be used for conf_file [internal use only] + char *schema; + double fetchz_x; + double fetchz_y; + double dem_z; + double dem_m; + int has_z; + int has_m; + int has_spatial_index; + int is_spatial_table; + int config_type; // dem=0 ; source=1; + unsigned int id_rowid; // For debugging + unsigned int count_points; // For debugging + unsigned int count_points_nr; // For debugging +}; +// -- -- ---------------------------------- -- +// Reading dem-conf +// Environment var 'SPATIALITE_DEM' +// - with path to dem-conf +// -> must be created by +// (or using same syntax as) write_demconfig +// -- -- ---------------------------------- -- +// if not found, the tool will look for a +// - 'spatialite_dem.conf' file in the active directory +// if not found, default values will be used +// -- -- ---------------------------------- -- +// - any line not starting +// -> with a '#' [comment] +// -> not containing a '=' will be ignored +// - any other line will look for specific +// keywords before the '=' +// -> unknown keywords will be ignored +// -- -- ---------------------------------- -- +struct config_dem get_demconfig(char *conf_filename, int verbose) +{ + struct config_dem config_struct; +// -- -- ---------------------------------- -- +// Setting default values +// -- -- ---------------------------------- -- + strcpy(config_struct.dem_path,""); + strcpy(config_struct.dem_table,""); + strcpy(config_struct.dem_geometry,""); + config_struct.dem_extent_minx=0.0; + config_struct.dem_extent_miny=0.0; + config_struct.dem_extent_maxx=0.0; + config_struct.dem_extent_maxy=0.0; + config_struct.dem_resolution=0.0; + config_struct.dem_srid=-2; // invalid + config_struct.default_srid=-2; // invalid + config_struct.dem_rows_count=0; +// -- -- ---------------------------------- -- +// Not to be used for conf_file [internal use only] +// -- -- ---------------------------------- -- + config_struct.fetchz_x=0.0; + config_struct.fetchz_y=0.0; + config_struct.dem_z=0.0; + config_struct.dem_m=0.0; + config_struct.has_z=0; + config_struct.has_m=0; + config_struct.has_spatial_index=0; + config_struct.is_spatial_table=0; + config_struct.schema=NULL; + config_struct.config_type=-1; + config_struct.id_rowid=0; // For debugging + config_struct.count_points=0; // For debugging + config_struct.count_points_nr=0; // For debugging +// -- -- ---------------------------------- -- + if ((conf_filename) && (strlen(conf_filename) > 0) ) + { + FILE *conf_file = fopen(conf_filename, "r"); + if (conf_file != NULL) + { + char line[MAXBUF]; + while(fgets(line, sizeof(line), conf_file) != NULL) + { + char *conf_parm=NULL; + char *conf_value=NULL; + conf_parm=(char *)line; + conf_value = strstr((char *)line,DELIM); + // Skip any comments (#) lines that may also contain a '=' + if ( (conf_parm[0] != '#') && (conf_value) ) + { + conf_parm[(int)(conf_value-conf_parm)]=0; + conf_value = conf_value + strlen(DELIM); + conf_value[strcspn(conf_value, "\r\n")] = 0; + // printf("parm[%s] value[%s]\n",conf_parm,conf_value); + if (strcmp(conf_parm,"dem_path") == 0) + { + strcpy(config_struct.dem_path,conf_value); + // printf("%s[%s]\n",conf_parm,config_struct.dem_path); + } else if (strcmp(conf_parm,"dem_table") == 0) + { + strcpy(config_struct.dem_table,conf_value); + // printf("%s[%s]\n",conf_parm,config_struct.dem_table); + } else if (strcmp(conf_parm,"dem_geometry") == 0) + { + strcpy(config_struct.dem_geometry,conf_value); + // printf("%s[%s]\n",conf_parm,config_struct.dem_geometry); + } else if (strcmp(conf_parm,"dem_extent_minx") == 0) + { + config_struct.dem_extent_minx=atof(conf_value); + //printf("%s[%2.7f]\n",conf_parm,config_struct.dem_extent_minx); + } else if (strcmp(conf_parm,"dem_extent_miny") == 0) + { + config_struct.dem_extent_miny=atof(conf_value); + //printf("%s[%2.7f]\n",conf_parm,config_struct.dem_extent_miny); + } else if (strcmp(conf_parm,"dem_extent_maxx") == 0) + { + config_struct.dem_extent_maxx=atof(conf_value); + //printf("%s[%2.7f]\n",conf_parm,config_struct.dem_extent_maxx); + } else if (strcmp(conf_parm,"dem_extent_maxy") == 0) + { + config_struct.dem_extent_maxy=atof(conf_value); + //printf("%s[%2.7f]\n",conf_parm,config_struct.dem_extent_maxy); + } else if (strcmp(conf_parm,"dem_resolution") == 0) + { + config_struct.dem_resolution=atof(conf_value); + //printf("%s[%2.7f]\n",conf_parm,config_struct.dem_resolution); + } else if (strcmp(conf_parm,"dem_srid") == 0) + { + config_struct.dem_rows_count=atol(conf_value); + // printf("%s[%d]\n",conf_parm,config_struct.dem_rows_count); + } else if (strcmp(conf_parm,"dem_srid") == 0) + { + config_struct.dem_srid=atoi(conf_value); + // printf("%s[%d]\n",conf_parm,config_struct.dem_srid); + } else if (strcmp(conf_parm,"default_srid") == 0) + { + config_struct.default_srid=atoi(conf_value); + // printf("%s[%d]\n",conf_parm,config_struct.default_srid); + } + } + } // End while + fclose(conf_file); + } // End if file + else + { + if (strcmp(conf_filename,"spatialite_dem.conf") != 0) + { + if (verbose) + { + fprintf(stderr, "-E-> spatialite_dem: not found: conf_filename[%s]\n",conf_filename); + } + } + } + } + return config_struct; +} +// -- -- ---------------------------------- -- +// writing dem-conf +// - any line not starting +// -> with a '#' [comment] +// -> not containing a '=' will be ignored +// - any other line will look for specific +// keywords before the '=' +// -> unknown keywords will be ignored +// -- -- ---------------------------------- -- +// Saving dem-conf '-save_conf' +// - will save to files set in 'SPATIALITE_DEM' +// - if empty to the default 'spatialite_dem.conf' +// -- -- ---------------------------------- -- +int write_demconfig(char *conf_filename, struct config_dem config_struct) +{ + int rc=0; + FILE *conf_file = fopen(conf_filename, "w"); + if (conf_file != NULL) + { + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fprintf(conf_file, "# For use with spatialite_dem\n"); + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fprintf(conf_file, "# export SPATIALITE_DEM=%s\n",conf_filename); + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fprintf(conf_file, "# Full path to Spatialite-Database containing a Dem-POINTZ (or POINTZM) Geometry\n"); + fprintf(conf_file, "dem_path=%s\n", config_struct.dem_path); + fprintf(conf_file, "# Table-Name containing a Dem-POINTZ (or POINTZM) Geometry\n"); + fprintf(conf_file, "dem_table=%s\n", config_struct.dem_table); + fprintf(conf_file, "# Geometry-Column containing a Dem-POINTZ (or POINTZM) Geometry\n"); + fprintf(conf_file, "dem_geometry=%s\n", config_struct.dem_geometry); + fprintf(conf_file, "# Srid of the Dem-Geometry\n"); + fprintf(conf_file, "dem_srid=%d\n", config_struct.dem_srid); + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fprintf(conf_file, "# Area around given point to Query Dem-Geometry in units of Dem-Srid\n"); + fprintf(conf_file, "# -> Rule: a Dem with 1m resolution: min=0.50\n"); + fprintf(conf_file, "dem_resolution=%2.7f\n", config_struct.dem_resolution); + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fprintf(conf_file, "# Default Srid to use for queries against Dem-Geometry [-fetchz_xy, -updatez]\n"); + fprintf(conf_file, "default_srid=%d\n", config_struct.default_srid); + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fprintf(conf_file, "# Count of rows in Dem-Geometry\n"); + fprintf(conf_file, "dem_rows_count=%u\n", config_struct.dem_rows_count); + fprintf(conf_file, "# Min X of Dem-Geometry\n"); + fprintf(conf_file, "dem_extent_minx=%2.7f\n", config_struct.dem_extent_minx); + fprintf(conf_file, "# Max X of Dem-Geometry\n"); + fprintf(conf_file, "dem_extent_maxx=%2.7f\n", config_struct.dem_extent_maxx); + fprintf(conf_file, "# Min Y of Dem-Geometry\n"); + fprintf(conf_file, "dem_extent_miny=%2.7f\n", config_struct.dem_extent_miny); + fprintf(conf_file, "# Max Y of Dem-Geometry\n"); + fprintf(conf_file, "dem_extent_maxy=%2.7f\n", config_struct.dem_extent_maxy); + fprintf(conf_file, "# Width of Dem-Area in Srid-Units\n"); + fprintf(conf_file, "dem_extent_width=%2.7f\n", (config_struct.dem_extent_maxx-config_struct.dem_extent_minx)); + fprintf(conf_file, "# Height of Dem-Area in Srid-Units\n"); + fprintf(conf_file, "dem_extent_height=%2.7f\n", (config_struct.dem_extent_maxy-config_struct.dem_extent_miny)); + fprintf(conf_file, "# -- -- ---------------------------------- --\n"); + fclose(conf_file); + rc=1; + } + return rc; +} +// -- -- ---------------------------------- -- +// From a given point, build area around it by 'resolution_dem' +// - utm 0.999 meters, Solder Berlin 1.0375644 meters +// (resolution_dem/2) could also be done +// - but to insure that at least 1 point is returned, left as is +// The nearest point will always be retrieved, or none at all. +// -- -- ---------------------------------- -- +static int +insert_dem_points(sqlite3 *db_handle, struct config_dem *dem_config, double *xx_source, double *yy_source, double *zz_source, int verbose) +{ + /* checking for 3D geometries - version 4 */ + int ret=0; + int ret_insert=SQLITE_OK; + int i=0; + char *sql_statement = NULL; + sqlite3_stmt *stmt = NULL; + char *sql_err = NULL; + if (zz_source) + { + sql_statement = sqlite3_mprintf("INSERT INTO \"%s\" (point_x,point_y, point_z,\"%s\") " + "VALUES(?,?,?,MakePointZ(?,?,?,%d)) ",dem_config->dem_table,dem_config->dem_geometry,dem_config->dem_srid); + ret = sqlite3_prepare_v2( db_handle, sql_statement, -1, &stmt, NULL ); + if ( ret == SQLITE_OK ) + { + sqlite3_free(sql_statement); + if (sqlite3_exec(db_handle, "BEGIN", NULL, NULL, &sql_err) == SQLITE_OK) + { + for (i=0; i<(int)(dem_config->count_points); i++) + { + if (ret_insert != SQLITE_ABORT ) + { + // Note: sqlite3_bind_* index is 1-based, os apposed to sqlite3_column_* that is 0-based. + sqlite3_bind_double(stmt, 1, xx_source[i]); + sqlite3_bind_double(stmt, 2, yy_source[i]); + sqlite3_bind_double(stmt, 3, zz_source[i]); + sqlite3_bind_double(stmt, 4, xx_source[i]); + sqlite3_bind_double(stmt, 5, yy_source[i]); + sqlite3_bind_double(stmt, 6, zz_source[i]); + dem_config->count_points_nr=i; + ret_insert = sqlite3_step( stmt ); + if ( ret_insert == SQLITE_DONE || ret_insert == SQLITE_ROW ) + { + ret_insert=SQLITE_OK; + } + else + { + ret_insert=SQLITE_ABORT; + } + } + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + xx_source[i]=0.0; + yy_source[i]=0.0; + zz_source[i]=0.0; + } + ret=0; + if (ret_insert == SQLITE_ABORT ) + { + if (sqlite3_exec(db_handle, "ROLLBACK", NULL, NULL, &sql_err) == SQLITE_OK) + { + ret=0; + } + } + else + { + if (sqlite3_exec(db_handle, "COMMIT", NULL, NULL, &sql_err) == SQLITE_OK) + { + ret = 1; + dem_config->dem_rows_count+=dem_config->count_points; + dem_config->count_points=0; + dem_config->count_points_nr=0; + } + } + } + sqlite3_finalize( stmt ); + if (sql_err) + { + sqlite3_free(sql_err); + } + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> insert_dem_points: rc=%d sql[%s]\n",ret,sql_statement); + } + sqlite3_free(sql_statement); + } + } + return ret; +} +// -- -- ---------------------------------- -- +// From a given point, build area around it by 'resolution_dem' +// - utm 0.999 meters, Solder Berlin 1.0375644 meters +// (resolution_dem/2) could also be done +// - but to insure that at least 1 point is returned, left as is +// The nearest point will always be retrieved, or none at all. +// -- -- ---------------------------------- -- +static int +retrieve_dem_points(sqlite3 *db_handle, struct config_dem *dem_config, int count_points, double *xx_source, double *yy_source, double *zz, double *mm, int *count_z, int *count_m, int verbose) +{ + /* checking for 3D geometries - version 4 */ + int ret=0; + int i=0; + char *sql_statement = NULL; + sqlite3_stmt *stmt = NULL; + int has_m = 0; + double x_source=0.0; + double y_source=0.0; + double z_source=0.0; + double m_source=0.0; + *count_z=0; + *count_m=0; + if (mm) + { + has_m = 1; + } + if (zz) + { + for (i=0; icount_points_nr=i; + x_source=xx_source[i]; + y_source=yy_source[i]; + /* checking the GEOMETRY_COLUMNS table */ + if (has_m) + { + sql_statement = sqlite3_mprintf("SELECT ST_Z(\"%s\"), ST_M(\"%s\") " + "FROM '%s'.'%s' WHERE (ROWID IN ( " + "SELECT ROWID FROM SpatialIndex WHERE ( " + "(f_table_name = 'DB=%s.%s') AND " + "(f_geometry_column = '%s') AND " + "(search_frame = ST_Buffer(MakePoint(%2.7f,%2.7f,%d),%2.7f)))) AND " + "(ST_ClosestPoint(%s, MakePoint(%2.7f,%2.7f,%d)) IS NOT Null) ) " + "ORDER BY ST_Distance(%s,MakePoint(%2.7f,%2.7f,%d)) ASC LIMIT 1" + ,dem_config->dem_geometry,dem_config->dem_geometry,dem_config->schema,dem_config->dem_table,dem_config->schema,dem_config->dem_table + ,dem_config->dem_geometry,x_source,y_source,dem_config->dem_srid,dem_config->dem_resolution + ,dem_config->dem_geometry,x_source,y_source,dem_config->dem_srid,dem_config->dem_geometry,x_source,y_source,dem_config->dem_srid); + } + else + { + sql_statement = sqlite3_mprintf("SELECT ST_Z(\"%s\") " + "FROM '%s'.'%s' WHERE (ROWID IN ( " + "SELECT ROWID FROM SpatialIndex WHERE (" + "(f_table_name = 'DB=%s.%s') AND " + "(f_geometry_column = '%s') AND " + "(search_frame = ST_Buffer(MakePoint(%2.7f,%2.7f,%d),%2.7f)))) AND " + "(ST_ClosestPoint(%s, MakePoint(%2.7f,%2.7f,%d)) IS NOT Null) ) " + "ORDER BY ST_Distance(%s,MakePoint(%2.7f,%2.7f,%d)) ASC LIMIT 1" + ,dem_config->dem_geometry,dem_config->schema,dem_config->dem_table,dem_config->schema,dem_config->dem_table + ,dem_config->dem_geometry,x_source,y_source,dem_config->dem_srid,dem_config->dem_resolution + ,dem_config->dem_geometry,x_source,y_source,dem_config->dem_srid,dem_config->dem_geometry,x_source,y_source,dem_config->dem_srid); + } + ret = sqlite3_prepare_v2( db_handle, sql_statement, -1, &stmt, NULL ); +#if 0 + if ((dem_config->id_rowid == 354) && (dem_config->count_points == 207)) + { + fprintf(stderr, "-III-> [EXTERIOR RING] -1a- cnt[%d,%d,%d] sql[%s] id_rowid[%d]\n",dem_config->count_points,dem_config->count_points_nr,ret,sql_statement,dem_config->id_rowid); + } +#endif + if ( ret == SQLITE_OK ) + { + sqlite3_free(sql_statement); + while ( sqlite3_step( stmt ) == SQLITE_ROW ) + { + if ( sqlite3_column_type( stmt, 0 ) != SQLITE_NULL ) + { + z_source = sqlite3_column_double (stmt, 0); + if ( (z_source != 0.0 ) && (zz[i] != z_source ) ) + {// Do not force an update if everything is 0 or has not otherwise changed + zz[i] = z_source; + *count_z += 1; + } + } + if ( sqlite3_column_type( stmt, 1 ) != SQLITE_NULL ) + { + m_source = sqlite3_column_double (stmt, 1); + if ( (m_source != 0.0 ) && (mm[i] != m_source ) ) + {// Do not force an update if everything is 0 or has not otherwise changed + mm[i] = m_source; + *count_m += 1; + } + mm[i] = sqlite3_column_double (stmt, 1); + } + } + sqlite3_finalize( stmt ); + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> retrieve_dem_points: rc=%d sql[%s]\n",ret,sql_statement); + } + sqlite3_free(sql_statement); + } + } + } +// printf("-I-> retrieve_dem_points: total[%d] not 0.0: z[%d] m[%d]\n",count_points,*count_z,*count_m); + if (*count_z > 0) + return 1; + return 0; +} +// -- -- ---------------------------------- -- +// +// -- -- ---------------------------------- -- +static int +callFetchZ(sqlite3 *db_handle, struct config_dem *dem_config, int verbose) +{ + int ret=0; + char *sql_statement = NULL; + sqlite3_stmt *stmt = NULL; + int i_count_z=0; + int i_count_m=0; + double *xx_use = NULL; + double *yy_use = NULL; + double *mm_use = NULL; + double *zz = NULL; +// -- -- ---------------------------------- -- + dem_config->dem_z=0;; + dem_config->dem_m=0; +// -- -- ---------------------------------- -- + if (dem_config->dem_srid != dem_config->default_srid ) + { + sql_statement = sqlite3_mprintf("SELECT ST_X(ST_Transform(MakePoint(%2.7f,%2.7f,%d),%d)), " + "ST_Y(ST_Transform(MakePoint(%2.7f,%2.7f,%d),%d))" + ,dem_config->fetchz_x, dem_config->fetchz_y, dem_config->default_srid,dem_config->dem_srid + ,dem_config->fetchz_x, dem_config->fetchz_y, dem_config->default_srid,dem_config->dem_srid); + ret = sqlite3_prepare_v2( db_handle, sql_statement, -1, &stmt, NULL ); + if ( ret == SQLITE_OK ) + { + sqlite3_free(sql_statement); + while ( sqlite3_step( stmt ) == SQLITE_ROW ) + { + if (( sqlite3_column_type( stmt, 0 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 1 ) != SQLITE_NULL ) ) + { + dem_config->fetchz_x = sqlite3_column_double(stmt, 0); + dem_config->fetchz_y = sqlite3_column_double(stmt, 1); + } + } + sqlite3_finalize( stmt ); + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> callFetchZ : rc=%d sql[%s]\n",ret,sql_statement); + } + sqlite3_free(sql_statement); + } + } +// -- -- ---------------------------------- -- + ret=0; + if ((dem_config->fetchz_x >= dem_config->dem_extent_minx) && (dem_config->fetchz_x <= dem_config->dem_extent_maxx) && + (dem_config->fetchz_y >= dem_config->dem_extent_miny) && (dem_config->fetchz_y <= dem_config->dem_extent_maxy ) ) + { + xx_use = malloc(sizeof (double) * 1); + yy_use = malloc(sizeof (double) * 1); + zz = malloc(sizeof (double) * 1); + mm_use = malloc(sizeof (double) * 1); + xx_use[0] = dem_config->fetchz_x; + yy_use[0] = dem_config->fetchz_y; + zz[0] = dem_config->dem_z; + mm_use[0] = dem_config->dem_m; + dem_config->count_points=1; + if (retrieve_dem_points(db_handle, dem_config, 1, xx_use, yy_use,zz,mm_use,&i_count_z, &i_count_m,verbose)) + { + ret=1; + dem_config->dem_z=zz[0]; + dem_config->dem_m=mm_use[0]; + } + free(xx_use); + free(yy_use); + free(zz); + free(mm_use); + xx_use = NULL; + yy_use = NULL; + mm_use = NULL; + zz = NULL; + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// GNU libc (Linux, and FreeBSD) +// - sys/param.h +// -- -- ---------------------------------- -- +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +// -- -- ---------------------------------- -- +// Based on gg_transform.c gaiaTransformCommon +// if the source geometry is out of range of the dem area, NULL is returned +// if the if the z or m values have not changed, NULL is returned +// - in both cases no update should be done and is not an error +// if the Dem-Database Geometry-Column uses a different Srid +// - a second Geometry will be sent with the transfored values +// --> those x,y values will be sent to retrieve_dem_points +// to retrieve the nearst point +// The retrieved z,m values will be copied WITHOUT any changes +// -- -- ---------------------------------- -- +static gaiaGeomCollPtr +getDemCollect(sqlite3 *db_handle, gaiaGeomCollPtr source_geom, gaiaGeomCollPtr dem_geom, struct config_dem *dem_config, + int *count_points_total, int *count_z_total, int *count_m_total, int verbose) +{ +// creates a new GEOMETRY replacing found z-points from the original one + int ib=0; + int cnt=0; + int i=0; + double *xx = NULL; + double *yy = NULL; + double *xx_dem = NULL; + double *yy_dem = NULL; + double *zz = NULL; + double *mm = NULL; + double *xx_use = NULL; + double *yy_use = NULL; + double *mm_use = NULL; + int count_z=0; + int count_m=0; + int i_count_z=0; + int i_count_m=0; + double x = 0.0; + double y = 0.0; + double z = 0.0; + double m = 0.0; + double extent_minx=0.0; + double extent_miny=0.0; + double extent_maxx=0.0; + double extent_maxy=0.0; + int error = 0; + int isExtentWithin=0; + gaiaPointPtr pt = NULL; + gaiaPointPtr pt_dem = NULL; + gaiaLinestringPtr ln = NULL; + gaiaLinestringPtr ln_dem = NULL; + gaiaLinestringPtr dst_ln = NULL; + gaiaPolygonPtr pg = NULL; + gaiaPolygonPtr pg_dem = NULL; + gaiaPolygonPtr dst_pg = NULL; + gaiaRingPtr rng = NULL; + gaiaRingPtr rng_dem = NULL; + gaiaRingPtr dst_rng = NULL; + gaiaGeomCollPtr dst = NULL; + if (source_geom->DimensionModel == GAIA_XY_Z) + dst = gaiaAllocGeomCollXYZ(); + else if (source_geom->DimensionModel == GAIA_XY_M) + dst = gaiaAllocGeomCollXYM(); + else if (source_geom->DimensionModel == GAIA_XY_Z_M) + dst = gaiaAllocGeomCollXYZM(); + else + dst = gaiaAllocGeomColl (); + cnt = 0; + dst->Srid = source_geom->Srid; + pt = source_geom->FirstPoint; + extent_minx=source_geom->MinX; + extent_miny=source_geom->MinY; + extent_maxx=source_geom->MaxX; + extent_maxy=source_geom->MaxY; + if (dem_geom) + { + extent_minx=dem_geom->MinX; + extent_miny=dem_geom->MinY; + extent_maxx=dem_geom->MaxX; + extent_maxy=dem_geom->MaxY; + } +// -- -- ---------------------------------- -- +// Touches (partially within) +// -- -- ---------------------------------- -- + int left_x = MAX(extent_minx, dem_config->dem_extent_minx); + int right_x = MIN(extent_maxx, dem_config->dem_extent_maxx); + int bottom_y = MAX(extent_miny, dem_config->dem_extent_miny); + int top_y = MIN(extent_maxy, dem_config->dem_extent_maxy); + if ((right_x > left_x) && (top_y > bottom_y)) + { + isExtentWithin=1; + } +// -- -- ---------------------------------- -- +#if 0 + if ((extent_minx >= dem_config->dem_extent_minx) && (extent_maxx <= dem_config->dem_extent_maxx) && + (extent_miny >= dem_config->dem_extent_miny) && (extent_maxy <= dem_config->dem_extent_maxy ) ) + { + isExtentWithin=1; + } +#endif + if (!isExtentWithin) + { + error=1; + goto stop; + } +// -- -- ---------------------------------- -- +// Call only if geometry is partially within the Dem extent +// -- -- ---------------------------------- -- +// Points +// -- -- ---------------------------------- -- + while (pt) + { + // counting POINTs + cnt++; + pt = pt->Next; + } + if (cnt) + { + // reprojecting POINTs + xx = malloc(sizeof (double) * cnt); + yy = malloc(sizeof (double) * cnt); + if (dem_geom) + { + xx_dem = malloc(sizeof (double) * cnt); + yy_dem = malloc(sizeof (double) * cnt); + xx_use = xx_dem; + yy_use = yy_dem; + } + else + { + xx_use = xx; + yy_use = yy; + } + zz = malloc(sizeof (double) * cnt); + if (source_geom->DimensionModel == GAIA_XY_M || source_geom->DimensionModel == GAIA_XY_Z_M) + mm = malloc(sizeof (double) * cnt); + i = 0; + pt = source_geom->FirstPoint; + if (dem_geom) + { + pt_dem = dem_geom->FirstPoint; + } + while (pt) + { + // inserting points to be converted in temporary arrays + xx[i] = pt->X; + yy[i] = pt->Y; + if (source_geom->DimensionModel == GAIA_XY_Z || source_geom->DimensionModel == GAIA_XY_Z_M) + zz[i] = pt->Z; + else + zz[i] = 0.0; + if (source_geom->DimensionModel == GAIA_XY_M || source_geom->DimensionModel == GAIA_XY_Z_M) + mm[i] = pt->M; + if (pt_dem) + { + xx_dem[i] = pt_dem->X; + yy_dem[i] = pt_dem->Y; + } + i++; + // -- -- ---------------------------------- -- + // MultiPoints, next + // -- -- ---------------------------------- -- + pt = pt->Next; + if (dem_geom) + { + pt_dem =pt_dem->Next; + } + } + if ((dem_config->has_m) && (mm) ) + { + mm_use = mm; + } + // searching for nearest point + *count_points_total+=cnt; + i_count_z=0; + i_count_m=0; + dem_config->count_points=cnt; + if (retrieve_dem_points(db_handle, dem_config, cnt, xx_use, yy_use,zz,mm_use,&i_count_z, &i_count_m,verbose)) + { + *count_z_total+=i_count_z; + *count_m_total+=i_count_m; + count_z+=i_count_z; + count_m+=i_count_m; + } + xx_use = NULL; + yy_use = NULL; + mm_use = NULL; + // inserting the reprojected POINTs in the new GEOMETRY + for (i = 0; i < cnt; i++) + { + x = xx[i]; + y = yy[i]; + if (source_geom->DimensionModel == GAIA_XY_Z || source_geom->DimensionModel == GAIA_XY_Z_M) + z = zz[i]; + else + z = 0.0; + if (source_geom->DimensionModel == GAIA_XY_M || source_geom->DimensionModel == GAIA_XY_Z_M) + m = mm[i]; + else + m = 0.0; + if (dst->DimensionModel == GAIA_XY_Z) + gaiaAddPointToGeomCollXYZ(dst, x, y, z); + else if (dst->DimensionModel == GAIA_XY_M) + gaiaAddPointToGeomCollXYM(dst, x, y, m); + else if (dst->DimensionModel == GAIA_XY_Z_M) + gaiaAddPointToGeomCollXYZM(dst, x, y, z, m); + else + gaiaAddPointToGeomColl(dst, x, y); + } + free(xx); + free(yy); + free(zz); + xx = NULL; + yy = NULL; + zz = NULL; + if (xx_dem) + { + free(xx_dem); + xx_dem = NULL; + free(yy_dem); + yy_dem = NULL; + } + if (source_geom->DimensionModel == GAIA_XY_M || source_geom->DimensionModel == GAIA_XY_Z_M) + { + free(mm); + mm = NULL; + } + } + if (error) + goto stop; +// -- -- ---------------------------------- -- +// Linestrings +// -- -- ---------------------------------- -- + ln = source_geom->FirstLinestring; + if (dem_geom) + { + ln_dem = dem_geom->FirstLinestring; + } +// Call only if geometry is inside the Dem extent + while (ln) + { + // reprojecting LINESTRINGs + cnt = ln->Points; + xx = malloc(sizeof (double) * cnt); + yy = malloc(sizeof (double) * cnt); + if (dem_geom) + { + xx_dem = malloc(sizeof (double) * cnt); + yy_dem = malloc(sizeof (double) * cnt); + xx_use = xx_dem; + yy_use = yy_dem; + } + else + { + xx_use = xx; + yy_use = yy; + } + zz = malloc(sizeof (double) * cnt); + if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) + mm = malloc(sizeof (double) * cnt); + for (i = 0; i < cnt; i++) + { + // inserting points to be converted in temporary arrays + if (ln->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ(ln->Coords, i, &x, &y, &z); + } + else if (ln->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM(ln->Coords, i, &x, &y, &m); + } + else if (ln->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM(ln->Coords, i, &x, &y, &z, &m); + } + else + { + gaiaGetPoint(ln->Coords, i, &x, &y); + } + xx[i] = x; + yy[i] = y; + if (ln_dem) + { + if (ln_dem->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ(ln_dem->Coords, i, &x, &y, &z); + } + else if (ln_dem->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM(ln->Coords, i, &x, &y, &m); + } + else if (ln_dem->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM(ln_dem->Coords, i, &x, &y, &z, &m); + } + else + { + gaiaGetPoint(ln_dem->Coords, i, &x, &y); + } + xx_dem[i] = x; + yy_dem[i] = y; + } + if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) + zz[i] = z; + else + zz[i] = 0.0; + if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) + mm[i] = m; + } + if ((dem_config->has_m) && (mm) ) + { + mm_use = mm; + } + // searching for nearest point + *count_points_total+=cnt; + i_count_z=0; + i_count_m=0; + dem_config->count_points=cnt; + if (retrieve_dem_points(db_handle, dem_config, cnt, xx_use, yy_use,zz,mm_use,&i_count_z, &i_count_m,verbose)) + { + *count_z_total+=i_count_z; + *count_m_total+=i_count_m; + count_z+=i_count_z; + count_m+=i_count_m; + } + xx_use = NULL; + yy_use = NULL; + mm_use = NULL; + // inserting the reprojected LINESTRING in the new GEOMETRY + dst_ln = gaiaAddLinestringToGeomColl (dst, cnt); + for (i = 0; i < cnt; i++) + { + // setting LINESTRING points + x = xx[i]; + y = yy[i]; + if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) + z = zz[i]; + else + z = 0.0; + if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) + m = mm[i]; + else + m = 0.0; + if (dst_ln->DimensionModel == GAIA_XY_Z) + { + gaiaSetPointXYZ (dst_ln->Coords, i, x, y, z); + } + else if (dst_ln->DimensionModel == GAIA_XY_M) + { + gaiaSetPointXYM(dst_ln->Coords, i, x, y, m); + } + else if (dst_ln->DimensionModel == GAIA_XY_Z_M) + { + gaiaSetPointXYZM(dst_ln->Coords, i, x, y, z, m); + } + else + { + gaiaSetPoint(dst_ln->Coords, i, x, y); + } + } + free(xx); + free(yy); + xx = NULL; + yy = NULL; + if (xx_dem) + { + free(xx_dem); + xx_dem = NULL; + free(yy_dem); + yy_dem = NULL; + } + free(zz); + zz = NULL; + if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) + { + free(mm); + mm = NULL; + } + if (error) + goto stop; +// -- -- ---------------------------------- -- +// MultiLinestrings, next +// -- -- ---------------------------------- -- + ln = ln->Next; + if (dem_geom) + { + ln_dem = ln_dem->Next; + } + } +// -- -- ---------------------------------- -- +// Polygons +// -- -- ---------------------------------- -- + pg = source_geom->FirstPolygon; + if (dem_geom) + { + pg_dem = dem_geom->FirstPolygon; + } + while (pg) + { + // -- -- ---------------------------------- -- + // Polygons-ExteriorRing + // -- -- ---------------------------------- -- + rng = pg->Exterior; + cnt = rng->Points; + dst_pg = gaiaAddPolygonToGeomColl(dst, cnt, pg->NumInteriors); + xx = malloc(sizeof (double) * cnt); + yy = malloc(sizeof (double) * cnt); + if (dem_geom) + { + xx_dem = malloc(sizeof (double) * cnt); + yy_dem = malloc(sizeof (double) * cnt); + rng_dem = pg_dem->Exterior; + xx_use = xx_dem; + yy_use = yy_dem; + } + else + { + xx_use = xx; + yy_use = yy; + } + zz = malloc(sizeof (double) * cnt); + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + mm = malloc(sizeof (double) * cnt); + for (i = 0; i < cnt; i++) + { + // inserting points to be converted in temporary arrays [EXTERIOR RING] + if (rng->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ(rng->Coords, i, &x, &y, &z); + } + else if (rng->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM(rng->Coords, i, &x, &y, &m); + } + else if (rng->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM(rng->Coords, i, &x, &y, &z, &m); + } + else + { + gaiaGetPoint(rng->Coords, i, &x, &y); + } + xx[i] = x; + yy[i] = y; + if (rng_dem) + { + if (rng_dem->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ(rng_dem->Coords, i, &x, &y, &z); + } + else if (rng_dem->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM(rng_dem->Coords, i, &x, &y, &m); + } + else if (rng_dem->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM(rng_dem->Coords, i, &x, &y, &z, &m); + } + else + { + gaiaGetPoint(rng_dem->Coords, i, &x, &y); + } + xx_dem[i] = x; + yy_dem[i] = y; + } + if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) + zz[i] = z; + else + zz[i] = 0.0; + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + mm[i] = m; + } + if ((dem_config->has_m) && (mm) ) + { + mm_use = mm; + } + // searching for nearest point + *count_points_total+=cnt; + i_count_z=0; + i_count_m=0; + dem_config->count_points=cnt; + if (retrieve_dem_points(db_handle, dem_config, cnt, xx_use, yy_use,zz,mm_use,&i_count_z, &i_count_m,verbose)) + { + *count_z_total+=i_count_z; + *count_m_total+=i_count_m; + count_z+=i_count_z; + count_m+=i_count_m; + } + xx_use = NULL; + yy_use = NULL; + mm_use = NULL; + // inserting the reprojected POLYGON in the new GEOMETRY + dst_rng = dst_pg->Exterior; + for (i = 0; i < cnt; i++) + { + // setting EXTERIOR RING points + x = xx[i]; + y = yy[i]; + if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) + z = zz[i]; + else + z = 0.0; + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + m = mm[i]; + else + m = 0.0; + if (dst_rng->DimensionModel == GAIA_XY_Z) + { + gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); + } + else if (dst_rng->DimensionModel == GAIA_XY_M) + { + gaiaSetPointXYM(dst_rng->Coords, i, x, y, m); + } + else if (dst_rng->DimensionModel == GAIA_XY_Z_M) + { + gaiaSetPointXYZM(dst_rng->Coords, i, x, y, z, m); + } + else + { + gaiaSetPoint(dst_rng->Coords, i, x, y); + } + } + free(xx); + free(yy); + xx = NULL; + yy = NULL; + if (xx_dem) + { + free(xx_dem); + xx_dem = NULL; + free(yy_dem); + yy_dem = NULL; + } + free(zz); + zz = NULL; + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + { + free(mm); + mm = NULL; + } + if (error) + goto stop; + // -- -- ---------------------------------- -- + // Polygons-InteriorRings + // -- -- ---------------------------------- -- + for (ib = 0; ib < pg->NumInteriors; ib++) + { + // processing INTERIOR RINGS + rng = pg->Interiors + ib; + cnt = rng->Points; + xx = malloc(sizeof (double) * cnt); + yy = malloc(sizeof (double) * cnt); + if (dem_geom) + { + xx_dem = malloc(sizeof (double) * cnt); + yy_dem = malloc(sizeof (double) * cnt); + rng_dem = pg_dem->Interiors + ib; + xx_use = xx_dem; + yy_use = yy_dem; + } + else + { + xx_use = xx; + yy_use = yy; + } + zz = malloc(sizeof (double) * cnt); + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + mm = malloc(sizeof (double) * cnt); + for (i = 0; i < cnt; i++) + { + // inserting points to be converted in temporary arrays [INTERIOR RING] + if (rng->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ(rng->Coords, i, &x, &y, &z); + } + else if (rng->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM(rng->Coords, i, &x, &y, &m); + } + else if (rng->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM(rng->Coords, i, &x, &y, &z, &m); + } + else + { + gaiaGetPoint(rng->Coords, i, &x, &y); + } + xx[i] = x; + yy[i] = y; + if (rng_dem) + { + if (rng_dem->DimensionModel == GAIA_XY_Z) + { + gaiaGetPointXYZ(rng_dem->Coords, i, &x, &y, &z); + } + else if (rng_dem->DimensionModel == GAIA_XY_M) + { + gaiaGetPointXYM(rng_dem->Coords, i, &x, &y, &m); + } + else if (rng_dem->DimensionModel == GAIA_XY_Z_M) + { + gaiaGetPointXYZM(rng_dem->Coords, i, &x, &y, &z, &m); + } + else + { + gaiaGetPoint(rng_dem->Coords, i, &x, &y); + } + xx_dem[i] = x; + yy_dem[i] = y; + } + if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) + zz[i] = z; + else + zz[i] = 0.0; + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + mm[i] = m; + } + if ((dem_config->has_m) && (mm) ) + { + mm_use = mm; + } + // searching for nearest point + *count_points_total+=cnt; + i_count_z=0; + i_count_m=0; + dem_config->count_points=cnt; + if (retrieve_dem_points(db_handle, dem_config, cnt, xx_use, yy_use,zz,mm_use,&i_count_z, &i_count_m,verbose)) + { + *count_z_total+=i_count_z; + *count_m_total+=i_count_m; + count_z+=i_count_z; + count_m+=i_count_m; + } + xx_use = NULL; + yy_use = NULL; + mm_use = NULL; + // inserting the reprojected POLYGON in the new GEOMETRY + dst_rng = gaiaAddInteriorRing(dst_pg, ib, cnt); + for (i = 0; i < cnt; i++) + { + // setting INTERIOR RING points + x = xx[i]; + y = yy[i]; + if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) + z = zz[i]; + else + z = 0.0; + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + m = mm[i]; + else + m = 0.0; + if (dst_rng->DimensionModel == GAIA_XY_Z) + { + gaiaSetPointXYZ(dst_rng->Coords, i, x, y, z); + } + else if (dst_rng->DimensionModel == GAIA_XY_M) + { + gaiaSetPointXYM(dst_rng->Coords, i, x, y, m); + } + else if (dst_rng->DimensionModel == GAIA_XY_Z_M) + { + gaiaSetPointXYZM(dst_rng->Coords, i, x, y, z, m); + } + else + { + gaiaSetPoint(dst_rng->Coords, i, x, y); + } + } + free(xx); + free(yy); + xx = NULL; + yy = NULL; + if (xx_dem) + { + free(xx_dem); + xx_dem = NULL; + free(yy_dem); + yy_dem = NULL; + } + free(zz); + zz = NULL; + if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) + { + free(mm); + mm = NULL; + } + if (error) + goto stop; + } +// -- -- ---------------------------------- -- +// MultiPolygons, next +// -- -- ---------------------------------- -- + pg = pg->Next; + if (dem_geom) + { + pg_dem = pg_dem->Next; + } + } +// -- -- ---------------------------------- -- +// -end- Geometry types +// -- -- ---------------------------------- -- +stop: + if ((count_z+count_m) == 0) + {// Do not force an update if everything is 0 or has not otherwise changed + error=1; + } + if (error) + { + // some error occurred, or no changes needed + gaiaPointPtr pP; + gaiaPointPtr pPn; + gaiaLinestringPtr pL; + gaiaLinestringPtr pLn; + gaiaPolygonPtr pA; + gaiaPolygonPtr pAn; + pP = dst->FirstPoint; + while (pP != NULL) + { + pPn = pP->Next; + gaiaFreePoint(pP); + pP = pPn; + } + pL = dst->FirstLinestring; + while (pL != NULL) + { + pLn = pL->Next; + gaiaFreeLinestring(pL); + pL = pLn; + } + pA = dst->FirstPolygon; + while (pA != NULL) + { + pAn = pA->Next; + gaiaFreePolygon(pA); + pA = pAn; + } + dst->FirstPoint = NULL; + dst->LastPoint = NULL; + dst->FirstLinestring = NULL; + dst->LastLinestring = NULL; + dst->FirstPolygon = NULL; + dst->LastPolygon = NULL; + gaiaFreeGeomColl(dst); + dst = NULL; + // -- -- ---------------------------------- -- + // if the source geometry is out of range of the dem area, NULL is returned + // -- -- ---------------------------------- -- + return NULL; + } + if (dst) + { + gaiaMbrGeometry(dst); + dst->DeclaredType = source_geom->DeclaredType; + } + return dst; +} +// -- -- ---------------------------------- -- +// if the source geometry is out of range of the dem area, NULL is returned +// - no update should be done and is not an error +// if the source geometry cannot be updated, when changed +// - this is an error and the loop should stop +// The source must be a SpatialTable, +// - since ROWID is used for a (possibly) needed update +// -- -- ---------------------------------- -- +static int +retrieve_geometries(sqlite3 *db_handle, struct config_dem *source_config, struct config_dem *dem_config, int *count_total_geometries, int *count_changed_geometries, + int *count_points_total, int *count_z_total, int *count_m_total, int verbose) +{ + char *sql_statement = NULL; + sqlite3_stmt *stmt = NULL; + sqlite3_stmt *stmt_update = NULL; + char *sql_err = NULL; + unsigned char *blob_value = NULL; + int blob_bytes=0; + unsigned char *blob_update = NULL; + int blob_bytes_update=0; + int id_rowid=0; + int ret=0; + int ret_update=SQLITE_ABORT; + unsigned int i_sleep=1; // 1 second + int count_geometries_remainder=100; + int transaction_update_changed_last=0; + int transaction_count_loops=0; + double remainder_calc=0.10; + gaiaGeomCollPtr source_geom = NULL; + gaiaGeomCollPtr geom_dem = NULL; + gaiaGeomCollPtr geom_result = NULL; + *count_total_geometries=0; + *count_changed_geometries=0; + *count_points_total=0; + *count_z_total=0; + *count_m_total=0; +// -- -- ---------------------------------- -- + count_geometries_remainder=source_config->dem_rows_count/100; + if (count_geometries_remainder > 1000) + {// Display results every 1.25% of total geometries, when verbose + remainder_calc=remainder_calc/8; + } else if (source_config->dem_rows_count > 500) + {// Display results every 2.5% of total geometries, when verbose + remainder_calc=remainder_calc/4; + } else if (source_config->dem_rows_count > 100) + {// Display results every 5% of total geometries, when verbose + remainder_calc=remainder_calc/2; + } // else: Display results every 10% of total geometries, when verbose + count_geometries_remainder=(int)(source_config->dem_rows_count*remainder_calc); +// -- -- ---------------------------------- -- + if (verbose) + { + fprintf(stderr, "-I-> retrieve_geometries: results will be shown after each group of %d geometries, total[%u] \n",count_geometries_remainder,source_config->dem_rows_count); + } + if (dem_config->default_srid == dem_config->dem_srid) + { + sql_statement = sqlite3_mprintf("SELECT ROWID, \"%s\" FROM '%s'.'%s' WHERE \"%s\" IS NOT NULL", + source_config->dem_geometry, source_config->schema,source_config->dem_table, source_config->dem_geometry); + } + else + { + sql_statement = sqlite3_mprintf("SELECT ROWID, \"%s\", ST_Transform(\"%s\",%d) FROM '%s'.'%s' WHERE \"%s\" IS NOT NULL", + source_config->dem_geometry,source_config->dem_geometry, dem_config->dem_srid, source_config->schema,source_config->dem_table,source_config->dem_geometry); + } + ret = sqlite3_prepare_v2(db_handle, sql_statement, -1, &stmt, NULL ); + if ( ret == SQLITE_OK ) + { + sqlite3_free(sql_statement); + while ( sqlite3_step( stmt ) == SQLITE_ROW ) + { + if (( sqlite3_column_type( stmt, 0 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 1 ) != SQLITE_NULL ) ) + { + id_rowid = sqlite3_column_int (stmt, 0); + dem_config->id_rowid=id_rowid; // for debugging + blob_value = (unsigned char *)sqlite3_column_blob(stmt, 1); + blob_bytes = sqlite3_column_bytes(stmt,1); + source_geom = gaiaFromSpatiaLiteBlobWkb(blob_value, blob_bytes); + *count_total_geometries+=1; + } + if ( sqlite3_column_type( stmt, 2 ) != SQLITE_NULL ) + { + blob_value = (unsigned char *)sqlite3_column_blob(stmt, 2); + blob_bytes = sqlite3_column_bytes(stmt,2); + geom_dem = gaiaFromSpatiaLiteBlobWkb(blob_value, blob_bytes); + } + if (source_geom) + { + // if the source geometry is out of range of the dem area, NULL is returned: this is not an error, but no update + geom_result=getDemCollect(db_handle, source_geom, geom_dem, dem_config, count_points_total,count_z_total,count_m_total,verbose); + gaiaFreeGeomColl(source_geom); + source_geom = NULL; + if (geom_dem) + { + gaiaFreeGeomColl(geom_dem); + geom_dem = NULL; + } + ret_update=SQLITE_OK; + if (geom_result) + { + sql_statement = sqlite3_mprintf("UPDATE '%s'.'%s' SET '%s'=? WHERE ROWID=%d", + source_config->schema,source_config->dem_table,source_config->dem_geometry,id_rowid); + ret=sqlite3_prepare_v2(db_handle, sql_statement, -1, &stmt_update, NULL); + if ( ret == SQLITE_OK) + { + sqlite3_free(sql_statement); + gaiaToSpatiaLiteBlobWkb(geom_result, &blob_update, &blob_bytes_update); + // Note: sqlite3_bind_* index is 1-based, os apposed to sqlite3_column_* that is 0-based. + sqlite3_bind_blob(stmt_update, 1, blob_update, blob_bytes_update, free); + ret_update = sqlite3_step( stmt_update ); + if ( ret_update == SQLITE_DONE || ret_update == SQLITE_ROW ) + { + ret_update=SQLITE_OK; + *count_changed_geometries += 1; + } + else + { + ret_update=SQLITE_ABORT; + } + sqlite3_finalize( stmt_update ); + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> retrieve_geometries [UPDATE]: rc=%d sql[%s]\n",ret,sql_statement); + } + sqlite3_free(sql_statement); + } + } + gaiaFreeGeomColl(geom_result); + geom_result = NULL; + if (((*count_total_geometries % count_geometries_remainder) == 0)) + { + if (*count_changed_geometries > transaction_update_changed_last) + {// Store results only if something has changed + // Note: while testing, this process stopped, with no further updates being reported. + // The assumption was that there was a logical error else where, which was not the case. + // This saving was build in to get to this point and analyse. [cause: missing Next for Linestrings/Polygon for dem_geom] + // Since the logic exists, that UPDATEs are only done after changes have been made + // This sporadic COMMIT/BEGIN has been retained. What is done is done. + if (sqlite3_exec(db_handle, "COMMIT", NULL, NULL, &sql_err) == SQLITE_OK) + { + sleep(i_sleep); + if (sqlite3_exec(db_handle, "BEGIN", NULL, NULL, &sql_err) == SQLITE_OK) + { + } + } + if (sql_err) + { + sqlite3_free(sql_err); + } + } + if (verbose) + { + double procent_diff=(double)(*count_total_geometries)/source_config->dem_rows_count; + remainder_calc=procent_diff*100; + if (transaction_count_loops == 0) + {// Show only once + fprintf(stderr,"-I-> converted geometries commited to Database: \n"); + } + transaction_count_loops++; + if (dem_config->has_m) + {// overwrite the previous message [\r] + fprintf(stderr, "\r %02.2f%% total read[%d] changed[%d] ; points total[%d] changed z[%d] changed m[%d] ",remainder_calc,*count_total_geometries,*count_changed_geometries,*count_points_total,*count_z_total,*count_m_total); + } + else + {// overwrite the previous message [\r] + fprintf(stderr, "\r %02.2f%% total read[%d] changed[%d] ; points total[%d] changed z[%d] ",remainder_calc,*count_total_geometries,*count_changed_geometries,*count_points_total,*count_z_total); + } + } + transaction_update_changed_last=*count_changed_geometries; + } + } + if (ret_update == SQLITE_ABORT ) + { + break; + } + } + sqlite3_finalize( stmt ); + if (verbose) + {// new line after last message [\n] + fprintf(stderr, "\n"); + } + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> retrieve_geometries [SELECT]: rc=%d sql[%s]\n",ret,sql_statement); + } + sqlite3_free(sql_statement); + } + if (ret_update == SQLITE_ABORT ) + { + return 0; + } + return 1; +} +// -- -- ---------------------------------- -- +// Retrieve information about given +// - table and geometry-column +// -> for Source and Dem geometries +// Dem +// - must be a POINTZ or POINTZM +// - SpatialIndex must exist +// - Extent and row_count +// -> to calculate resolution +// Source +// - must have a Z or ZM Dimension +// Both +// - Srid of geometries +// -- -- ---------------------------------- -- +static int +check_geometry_dimension(sqlite3 *db_handle, struct config_dem *use_config, int *geometry_type, int verbose) +{ + /* checking the table, geometry exists and if the geometry supports z-values */ + int ret=0; + char *sql_statement = NULL; + sqlite3_stmt *stmt = NULL; + int *srid_default = NULL; + use_config->has_z = 0; + use_config->has_m = 0; + use_config->dem_extent_minx=0.0; + use_config->dem_extent_miny=0.0; + use_config->dem_extent_maxx=0.0; + use_config->dem_extent_maxy=0.0; + use_config->has_spatial_index=0; + use_config->is_spatial_table=0; + if (use_config->config_type == CONF_TYPE_DEM ) + { + srid_default = &use_config->dem_srid; + } + else + { + srid_default = &use_config->default_srid; + } + *geometry_type = 0; + *srid_default = 0; +// 390718.000000 5818887.000000 392757.000000 5820847.000000 +// 392757-390718=2039 +// 5820847-5818887=1960 +// 1960*2039=3996440/4000440=0.99900011 resolution + sql_statement = sqlite3_mprintf("SELECT a.geometry_type, a.srid, a.spatial_index_enabled, a.layer_type, " + "b.extent_min_x, b.extent_min_y, b.extent_max_x, b.extent_max_y, b.row_count " + "FROM '%s'.vector_layers AS a LEFT JOIN '%s'.vector_layers_statistics AS b " + "ON a.table_name=b.table_name AND a.geometry_column=b.geometry_column " + "WHERE a.table_name='%s' AND a.geometry_column='%s'", use_config->schema, use_config->schema, + use_config->dem_table, use_config->dem_geometry); + ret = sqlite3_prepare_v2(db_handle, sql_statement, -1, &stmt, NULL ); + if ( ret == SQLITE_OK ) + { + sqlite3_free(sql_statement); + while ( sqlite3_step( stmt ) == SQLITE_ROW ) + { + if (( sqlite3_column_type( stmt, 0 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 1 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 2 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 3 ) != SQLITE_NULL )) + { + *geometry_type = sqlite3_column_int( stmt, 0 ); + *srid_default = sqlite3_column_int( stmt, 1 ); + use_config->has_spatial_index = sqlite3_column_int( stmt, 2 ); + if (strcmp((const char *)sqlite3_column_text( stmt, 3 ),"SpatialTable") == 0) + { + // The source Database must be in a SpatialTable to be updated [no checking for writable SpatialView's] + // will be using ROWID to UPDATE + use_config->is_spatial_table = 1; + } + // printf("-I-> check_geometry_dimension: coord_dimension=%d GAIA_XY_*l[%d,%d,%d]\n",coord_dimension,GAIA_XY_Z,GAIA_XY_Z_M,GAIA_XY_M); + switch (*geometry_type) + { + case GAIA_POINTZ: + case GAIA_LINESTRINGZ: + case GAIA_POLYGONZ: + case GAIA_MULTIPOINTZ: + case GAIA_MULTILINESTRINGZ: + case GAIA_MULTIPOLYGONZ: + case GAIA_GEOMETRYCOLLECTIONZ: + use_config->has_z = 1; + break; + } + switch (*geometry_type) + { + case GAIA_POINTZM: + case GAIA_LINESTRINGZM: + case GAIA_POLYGONZM: + case GAIA_MULTIPOINTZM: + case GAIA_MULTILINESTRINGZM: + case GAIA_MULTIPOLYGONZM: + case GAIA_GEOMETRYCOLLECTIONZM: + use_config->has_z = 1; + use_config->has_m = 1; + break; + } + switch (*geometry_type) + { + case GAIA_POINTM: + case GAIA_LINESTRINGM: + case GAIA_POLYGONM: + case GAIA_MULTIPOINTM: + case GAIA_MULTILINESTRINGM: + case GAIA_MULTIPOLYGONM: + case GAIA_GEOMETRYCOLLECTIONM: + use_config->has_m = 1; + break; + } + } + if (( sqlite3_column_type( stmt, 4 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 5 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 6 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 7 ) != SQLITE_NULL ) && + ( sqlite3_column_type( stmt, 8 ) != SQLITE_NULL )) + { + use_config->dem_extent_minx = sqlite3_column_double( stmt, 4 ); + use_config->dem_extent_miny = sqlite3_column_double( stmt, 5 ); + use_config->dem_extent_maxx = sqlite3_column_double( stmt, 6 ); + use_config->dem_extent_maxy = sqlite3_column_double( stmt, 7 ); + use_config->dem_rows_count = sqlite3_column_int64( stmt, 8 ); + } + } + sqlite3_finalize( stmt ); + if ((use_config->is_spatial_table == 1) && (use_config->has_z) && (use_config->dem_rows_count > 0)) + { + ret=1; // Valid for usage + } + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> check_geometry_dimension: rc=%d sql[%s]\n",ret,sql_statement); + } + sqlite3_free(sql_statement); + } + return ret; +} +static void +spatialite_autocreate(sqlite3 *db_handle) +{ + /* attempting to perform self-initialization for a newly created DB */ + int ret; + char sql[1024]; + char *err_msg = NULL; + int count; + int i; + char **results; + int rows; + int columns; + + /* checking if this DB is really empty */ + strcpy(sql, "SELECT Count(*) from sqlite_master"); + ret = sqlite3_get_table(db_handle, sql, &results, &rows, &columns, NULL); + if (ret != SQLITE_OK) + return; + if (rows < 1) + ; + else + { + for (i = 1; i <= rows; i++) + count = atoi (results[(i * columns) + 0]); + } + sqlite3_free_table(results); + + if (count > 0) + return; + + /* all right, it's empty: proceding to initialize */ + strcpy(sql, "SELECT InitSpatialMetadataFull(1)"); + ret = sqlite3_exec(db_handle, sql, NULL, NULL, &err_msg); + if (ret != SQLITE_OK) + { + fprintf(stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); + sqlite3_free(err_msg); + return; + } +} +// -- -- ---------------------------------- -- +// Collecting a list of Dem-xyz file +// - with checks on the first record +// Case 1: a single xyz.file is given +// -> the file will be checked and added to the list +// Case 2: a directory is given +// -> each file will be checked and added to the list +// Case 3: a single list.file is given +// - contains a list of single xyz.files to be read +// -> expected to be inside the given directory +// -> each file will be checked and added to the list +// -- -- ---------------------------------- -- +// The list is the TABLE db_memory.xyz_files +// Goal is to read the files in a specific order: +// --> y='South to North' and x='West to East' +// -- -- ---------------------------------- -- +static int +collect_xyz_files(sqlite3 *db_handle,const char *xyz_filename, int *count_xyz_files, int verbose) +{ + int ret=0; + int i_count_fields=0; + int i_count_fields_check=3; + int ret_insert=SQLITE_OK; + if (*count_xyz_files < 0) + { + *count_xyz_files=0; + } + double point_x=0.0; + double point_y=0.0; + double point_z=0.0; + char *sql_statement = NULL; + int result_file_type=0; + char *directory_from_filename = NULL; +// -- -- ---------------------------------- -- + FILE *xyz_file = fopen(xyz_filename, "rt"); + if (xyz_file != NULL) + { + if (verbose) + { + fprintf(stderr,"-I-> collect_xyz_files:reading xyz_filename[%s] \n", xyz_filename); + } + char line[MAXBUF]; + while(fgets(line, sizeof(line), xyz_file) != NULL) + { + if (strcmp(line, "SQLite format 3") != 0) + { + line[strcspn(line, "\r\n")] = 0; + char *token; + char *ptr_strtod; + char *saveptr; + i_count_fields=0; + token = strtok_r(line, " ",&saveptr); + point_x=strtod(token, &ptr_strtod); + // atof will cause a signal 11 (SIGSEGV), if token does not contain a double + if ((int)strlen(ptr_strtod) == 0) + { + i_count_fields++; + while(token != NULL) + { + token = strtok_r(NULL," ",&saveptr); + switch (i_count_fields) + { + case 1: + point_y=strtod(token, &ptr_strtod); + if ((int)strlen(ptr_strtod) == 0) + { + i_count_fields++; + } + break; + case 2: + point_z=strtod(token, &ptr_strtod); + if ((int)strlen(ptr_strtod) == 0) + { + i_count_fields++; + } + break; + } + } + } + if (i_count_fields == 0) + { + // This may be a list of xyz.file-names, + // - contained in the same directory + // - that should be read [possibly not all of the xyz.files should be read] + // - order is not important, will be sorted by point_y ASC, point_x ASC of the first record + if (!directory_from_filename) + { + const char *slash = strrchr(xyz_filename,'/'); + directory_from_filename=malloc(sizeof(char)*((slash-xyz_filename)+1)); + strncpy(directory_from_filename,xyz_filename,slash-xyz_filename); + directory_from_filename[(slash-xyz_filename)]=0; + } + sql_statement = sqlite3_mprintf("%s/%s", directory_from_filename,token); + // the first record will be read. If 3 doubles, seperated by a space, can be created + // 1 : will be returned, after adding the path/file-name, point_x and point_y to db_memory.xyz_files + result_file_type=collect_xyz_files(db_handle,sql_statement, count_xyz_files, 0); + if (result_file_type == 1) + {//file_name has been added to db_memory.xyz_files + ret=1; // xyz-format + } + sqlite3_free(sql_statement); + } + if (i_count_fields == i_count_fields_check) + { + sql_statement = sqlite3_mprintf("INSERT INTO db_memory.xyz_files (point_x,point_y,file_name) " + "VALUES(%2.7f,%2.7f,'%s') ",point_x,point_y,xyz_filename); + if (db_handle) + { + if (sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL) == SQLITE_OK) + { + *count_xyz_files+=1; // xyz-format + result_file_type=1; + } + } + sqlite3_free(sql_statement); + ret_insert = SQLITE_ABORT; + } + if (verbose) + { + fprintf(stderr,"-I-> collect_xyz_files: i_count_fields[%d] check[%d] count_files[%d]\n", i_count_fields,i_count_fields_check,*count_xyz_files); + } + } + else + { + result_file_type=2; // Sqlite3-format + } + if (ret_insert == SQLITE_ABORT ) + { + break; + } + if (ret_insert != SQLITE_ABORT ) + { + // if this is a list of .xyz files that are being added, + // result_file_type will be 1, but not SQLITE_ABORT + // - since all entries must be read + if (result_file_type != 1) + { + break; // unknown format + } + } + } // End while + fclose(xyz_file); + if (directory_from_filename) + { + free(directory_from_filename); + directory_from_filename=NULL; + } + } // Checking for a file + else + { +#if defined(_WIN32) && !defined(__MINGW32__) + /* Visual Studio .NET */ + struct _finddata_t c_file; + intptr_t hFile; + char *name; + int len; + int ret; + if (_chdir (in_dir) < 0) + return ret; + if ((hFile = _findfirst ("*.xyz", &c_file)) == -1L) + ; + else + { + while (1) + {// A directory with .xyz files + if ((c_file.attrib & _A_RDONLY) == _A_RDONLY || (c_file.attrib & _A_NORMAL) == _A_NORMAL) + { + sql_statement = sqlite3_mprintf("%s/%s", xyz_filename,c_file.name); + if (collect_xyz_files(db_handle,sql_statement, count_xyz_files, 0) == 1) + {//file_name has been added to db_memory.xyz_files + } + sqlite3_free(sql_statement); + } + if (_findnext (hFile, &c_file) != 0) + break; + } + _findclose (hFile); + } +#else + DIR *xyz_dir = opendir(xyz_filename); + struct dirent *dir; + if (xyz_dir) + { + while ((dir = readdir(xyz_dir)) != NULL) + { + if (dir->d_type == DT_REG) + { + const char *ext = strrchr(dir->d_name,'.'); + if ((ext) || (ext != dir->d_name)) + { + if (strcmp(ext, ".xyz") == 0) + {// A directory with .xyz files + // - order is not important, will be sorted by point_y ASC, point_x ASC of the first record + sql_statement = sqlite3_mprintf("%s/%s", xyz_filename,dir->d_name); + // the first record will be read. If 3 doubles, seperated by a space, can be created + // 1 : will be returned, after adding the path/file-name, point_x and point_y to db_memory.xyz_files + result_file_type=collect_xyz_files(db_handle,sql_statement, count_xyz_files, 0); + if (result_file_type == 1) + {//file_name has been added to db_memory.xyz_files + } + sqlite3_free(sql_statement); + } + } + } + } + closedir(xyz_dir); + } // Checking for a directory +#endif + } +// -- -- ---------------------------------- -- + if (*count_xyz_files > 0) + { + ret=1; // xyz-format + } + else + { + ret=0; // not supported + if (verbose) + { + fprintf(stderr,"-E-> collect_xyz_files: import.xyz file format not found [%s]\n", xyz_filename); + } + } +// -- -- ---------------------------------- - + return ret; +} +// -- -- ---------------------------------- -- +// Read list of Dem-xyz files +// - from db_memory.xyz_files +// Goal is to INSERT the points in a specific order: +// --> y='South to North' and x='West to East' +// -- -- ---------------------------------- -- +static int +import_xyz(sqlite3 *db_handle, struct config_dem *dem_config, int count_xyz_files, int verbose) +{ + int ret=0; + int ret_select=0; + sqlite3_stmt *stmt = NULL; + char *sql_statement = NULL; + int i_count_loop=100000; + int i_count_fields=0; + int i_count_fields_check=3; + int i_count_in_loop=0; + int i_file_count=0; + const char *xyz_path_filename; +// 18.446.744.073.709.551.615 + unsigned int i_sleep=1; // 1 second + double point_x=0.0; + double point_y=0.0; + double point_z=0.0; + double *xx = NULL; + double *yy = NULL; + double *zz = NULL; + int ret_insert=SQLITE_OK; + if (count_xyz_files > 0) + {// input-files should be sorted from y='South to North' and x='West to East': sort -n -k2 -k1 input_file.xyz -o output_file.sort.xyz + // Select files sorted by y='South to North' and x='West to East' + sql_statement = sqlite3_mprintf("SELECT file_name FROM db_memory.xyz_files ORDER BY point_y ASC, point_x ASC"); + ret_select = sqlite3_prepare_v2(db_handle, sql_statement, -1, &stmt, NULL ); + sqlite3_free(sql_statement); + if ( ret_select == SQLITE_OK ) + { + while ( sqlite3_step( stmt ) == SQLITE_ROW ) + { + if ( sqlite3_column_type( stmt, 0 ) != SQLITE_NULL ) + { + xyz_path_filename=(const char *) sqlite3_column_text (stmt, 0); + // -- -- ---------------------------------- -- + FILE *xyz_file = fopen(xyz_path_filename, "rt"); + if (xyz_file != NULL) + { + char line[MAXBUF]; + i_file_count++; + i_count_in_loop=0; + if (verbose) + { + // CPU: 4-11% ; memory 9.3 Ḿib ; normal working with mouse and applications + fprintf(stderr,"import_xyz: reading xyz_filename[%s]\n (file %d of %d) in steps of [%u].\n",xyz_path_filename,i_file_count,count_xyz_files, i_count_loop); + } + xx = malloc(sizeof (double) * i_count_loop); + yy = malloc(sizeof (double) * i_count_loop); + zz = malloc(sizeof (double) * i_count_loop); + while(fgets(line, sizeof(line), xyz_file) != NULL) + { + line[strcspn(line, "\r\n")] = 0; + char *token; + char *ptr_strtod; + char *saveptr; + i_count_fields=0; + token = strtok_r(line, " ",&saveptr); + point_x=strtod(token, &ptr_strtod); + // atof will cause a signal 11 (SIGSEGV), if token does not contain a double + if ((int)strlen(ptr_strtod) == 0) + { + i_count_fields++; + while(token != NULL) + { + token = strtok_r(NULL," ",&saveptr); + switch (i_count_fields) + { + case 1: + point_y=strtod(token, &ptr_strtod); + if ((int)strlen(ptr_strtod) == 0) + { + i_count_fields++; + } + break; + case 2: + point_z=strtod(token, &ptr_strtod); + if ((int)strlen(ptr_strtod) == 0) + { + i_count_fields++; + } + break; + } + } + } + if (i_count_fields == i_count_fields_check) + { + if (i_count_in_loop < i_count_loop) + { + xx[i_count_in_loop]=point_x; + yy[i_count_in_loop]=point_y; + zz[i_count_in_loop]=point_z; + i_count_in_loop++; + } + if (i_count_in_loop == i_count_loop) + { + dem_config->count_points=i_count_in_loop; + if (!insert_dem_points(db_handle, dem_config, xx, yy, zz, verbose)) + { + // Inserting failed, abort + ret_insert = SQLITE_ABORT; + } + else + { + if (verbose) + { + fprintf(stderr,"\r inserted [%u] ... ", dem_config->dem_rows_count); + } + } + // xx,yy,zz values are reset to 0.0 in insert_dem_points + i_count_in_loop=0; + sleep(i_sleep); + } + } + else + { + ret_insert = SQLITE_ABORT; + } + if (ret_insert == SQLITE_ABORT ) + { + break; + } + } // End while + fclose(xyz_file); + // -- -- ---------------------------------- -- + // Complete what is left over, when no abort + // -- -- ---------------------------------- -- + if (ret_insert != SQLITE_ABORT ) + { + ret=1; + if ( i_count_in_loop < i_count_loop) + { + ret=0; + dem_config->count_points=i_count_in_loop; + fprintf(stderr,"import_xyz: calling insert_dem_points: i_count_in_loop[%d].\n",dem_config->count_points); + if (insert_dem_points(db_handle, dem_config, xx, yy, zz, verbose)) + { + ret=1; + if (verbose) + { + fprintf(stderr,"\r file%d: inserting compleated [%u]\n",i_file_count, dem_config->dem_rows_count); + } + } + } + } + // -- -- ---------------------------------- -- + // clean up + // -- -- ---------------------------------- -- + if (xx) + { + free(xx); + xx=NULL; + } + if (yy) + { + free(yy); + yy=NULL; + } + if (zz) + { + free(zz); + zz=NULL; + } + } + else + { + if (verbose) + { + fprintf(stderr,"-E-> import_xyz: import.xyz file not found [%s]\n", xyz_path_filename); + } + } + } + } + sqlite3_finalize( stmt ); + } + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Recover Dem-Geometry with SpatialIndex +// - recovering a full Geometry Column +// -- -- ---------------------------------- -- +static int +recover_geometry_dem(sqlite3 *db_handle, struct config_dem *dem_config, int verbose) +{ + /* recovering a full Geometry Column */ + int ret; + char *err_msg; + char *sql_statement = NULL; + if (verbose) + { + fprintf(stderr,"Recovering Geometry: %s(%s) as POINTZ with srid=%d\n", dem_config->dem_table,dem_config->dem_geometry, dem_config->dem_srid); + } + sql_statement = sqlite3_mprintf("SELECT RecoverGeometryColumn(%Q, %Q, %d, %Q, %Q)", + dem_config->dem_table,dem_config->dem_geometry, dem_config->dem_srid, "POINT", "XYZ"); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, &err_msg); + sqlite3_free(sql_statement); + if (ret != SQLITE_OK) + { + if (verbose) + { + fprintf(stderr, "RecoverGeometryColumn error: %s\n", err_msg); + } + sqlite3_free(err_msg); + return 0; + } + if (verbose) + { + fprintf(stderr, "Creating Spatial Index: %s(%s)\n", dem_config->dem_table,dem_config->dem_geometry); + } + sql_statement = sqlite3_mprintf("SELECT CreateSpatialIndex(%Q, %Q)", dem_config->dem_table,dem_config->dem_geometry); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, &err_msg); + sqlite3_free(sql_statement); + if (ret != SQLITE_OK) + { + fprintf(stderr, "CreateSpatialIndex error: %s\n", err_msg); + sqlite3_free(err_msg); + return 0; + } + if (verbose) + { + fprintf(stderr,"UpdateLayerStatistics: %s(%s)\n", dem_config->dem_table,dem_config->dem_geometry); + } + sql_statement = sqlite3_mprintf("SELECT UpdateLayerStatistics(%Q, %Q)", dem_config->dem_table,dem_config->dem_geometry); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, &err_msg); + sqlite3_free(sql_statement); + if (ret != SQLITE_OK) + { + fprintf(stderr, "UpdateLayerStatistics error: %s\n", err_msg); + sqlite3_free(err_msg); + return 0; + } + return 1; +} +// -- -- ---------------------------------- -- +// Create the Database for Dem +// - CREATE TABLE for minimal Dem-Data +// -> db_memory.xyz_files +// -- -- ---------------------------------- -- +static int +create_dem_db(const char *path_dem, sqlite3 ** handle, void *cache, const char *table_dem, const char *column_dem, int verbose) +{ + /* opening the DB */ + sqlite3 *db_handle = NULL; + int ret=0; + char *sql_statement = NULL; + *handle = NULL; + if ( verbose ) + { + fprintf(stderr,"SQLite version: %s\n", sqlite3_libversion()); + fprintf(stderr,"SpatiaLite version: %s\n\n", spatialite_version()); + } + FILE *db_file = fopen(path_dem, "r"); + if (db_file != NULL) + { + fclose(db_file); + return ret; + } + ret = sqlite3_open_v2(path_dem, &db_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "cannot open '%s': %s\n", path_dem, sqlite3_errmsg (db_handle)); + sqlite3_close(db_handle); + return ret; + } + spatialite_init_ex(db_handle, cache, 0); + spatialite_autocreate(db_handle); + if ( (table_dem) && ( column_dem ) ) + { + sql_statement = sqlite3_mprintf("CREATE TABLE \"%s\" (" + "id_dem INTEGER PRIMARY KEY AUTOINCREMENT, " + "point_x DOUBLE DEFAULT 0, " + "point_y DOUBLE DEFAULT 0, " + "point_z DOUBLE DEFAULT 0, " + "%s BLOB DEFAULT NULL)" + ,table_dem, column_dem); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "cannot CREATE Table: '%s' sql[%s]\n\t: %s\n", table_dem, sql_statement, sqlite3_errmsg (db_handle)); + sqlite3_free(sql_statement); + sqlite3_close(db_handle); + return ret; + } + sqlite3_free(sql_statement); + if (verbose) + { + fprintf(stderr,"Created table(geometry): %s(%s)\n", table_dem, column_dem); + } + sql_statement = sqlite3_mprintf("ATTACH DATABASE ':memory:' AS db_memory"); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + sqlite3_free(sql_statement); + if (ret == SQLITE_OK) + { + sql_statement = sqlite3_mprintf("CREATE TABLE db_memory.xyz_files (" + "file_name TEXT DEFAULT '', " + "point_x DOUBLE DEFAULT 0, " + "point_y DOUBLE DEFAULT 0)"); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + sqlite3_free(sql_statement); + if (ret != SQLITE_OK) + { + } + } + } + *handle = db_handle; + ret=1; + return ret; +} +// -- -- ---------------------------------- -- +// Close the Database +// - DETACH a connected Database if needed +// -> db_memory +// -- -- ---------------------------------- -- +static void +close_db(sqlite3 *db_handle, void *cache, const char *schema_dem) +{ + char *sql_statement = NULL; + int ret=0; + if (schema_dem) + { + if (strcmp(schema_dem, "main") != 0) + { + sql_statement = sqlite3_mprintf("DETACH DATABASE %s", schema_dem); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + sqlite3_free(sql_statement); + } + } + sql_statement = sqlite3_mprintf("DETACH DATABASE db_memory"); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + sqlite3_free(sql_statement); + sqlite3_close(db_handle); + if (cache) + { + spatialite_cleanup_ex(cache); + } + spatialite_shutdown(); + return; +} +// -- -- ---------------------------------- -- +// Open the Database +// - ATTACH a connected Database if needed +// While 'sniffing' a second source may not be needed +// - CREATE TABLE for minimal Dem-Data +// -> db_memory.xyz_files +// -- -- ---------------------------------- -- +static int +open_db(sqlite3 **handle, void *cache, struct config_dem *source_config, struct config_dem *dem_config, int verbose) +{ + /* opening the DB */ + sqlite3 *db_handle = NULL; + int ret=0; + char *sql_statement = NULL; + const char *path_db=NULL; + const char *path_attach=NULL; + const char *schema_db=NULL; + const char *schema_attach=NULL; + *handle = NULL; + if ( verbose ) + { + fprintf(stderr,"SQLite version: %s\n", sqlite3_libversion()); + fprintf(stderr,"SpatiaLite version: %s\n\n", spatialite_version()); + } + if ((strlen(dem_config->dem_path) > 0) && ( (source_config) && (strlen(source_config->dem_path) == 0))) + { + // Open the Dem-Database as source [sniff without source or fetchz] + path_db=dem_config->dem_path; + dem_config->schema="main"; + schema_attach=dem_config->schema; + } + else + { + path_db=source_config->dem_path; + schema_db=source_config->schema; + path_attach=dem_config->dem_path; + schema_attach=dem_config->schema; + } + ret = sqlite3_open_v2(path_db, &db_handle, SQLITE_OPEN_READWRITE, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "cannot open '%s': %s\n", path_db, sqlite3_errmsg (db_handle)); + close_db(db_handle, cache, NULL); + return 0; + } + if (path_attach) + { + sql_statement = sqlite3_mprintf("ATTACH DATABASE \"%s\" AS %s",path_attach, schema_attach); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "cannot ATTACH Database: '%s' sql[%s]\n\t: %s\n", path_attach, sql_statement, sqlite3_errmsg (db_handle)); + sqlite3_free(sql_statement); + close_db(db_handle, cache, NULL); + return 0; + } + sqlite3_free(sql_statement); + } + sql_statement = sqlite3_mprintf("ATTACH DATABASE ':memory:' AS db_memory"); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + sqlite3_free(sql_statement); + if (ret == SQLITE_OK) + { + sql_statement = sqlite3_mprintf("CREATE TABLE db_memory.xyz_files (" + "file_name TEXT DEFAULT '', " + "point_x DOUBLE DEFAULT 0, " + "point_y DOUBLE DEFAULT 0)"); + ret = sqlite3_exec(db_handle, sql_statement, NULL, NULL, NULL); + sqlite3_free(sql_statement); + if (ret != SQLITE_OK) + { + } + } + spatialite_init_ex(db_handle, cache, 0); + *handle = db_handle; + return 1; +} +// -- -- ---------------------------------- -- +// Help Messages +// -- -- ---------------------------------- -- +static void +do_help() +{ + /* printing the argument list */ + fprintf(stderr, "\n\nusage: spatialite_dem ARGLIST\n"); + fprintf(stderr, "==============================================================\n"); + fprintf(stderr, "-h or --help print this help message\n"); + fprintf(stderr, "========================== Parameters ========================\n"); + fprintf(stderr, " -- -- ---------------- Dem-Data Database ---------------- --\n"); + fprintf(stderr, "-ddem or --dem-path pathname to the SpatiaLite Dem DB \n"); + fprintf(stderr, "-tdem or --table-dem table_name [SpatialTable or SpatialView]\n"); + fprintf(stderr, "-gdem or --geometry-dem-column col_name the Geometry column\n"); + fprintf(stderr, "\t must be a POINT Z or a POINT ZM type\n"); + fprintf(stderr, "-rdem or --dem-resolution of the dem points while searching\n"); + fprintf(stderr, "\t the automatic resolution calculation is based on the row_count\n"); + fprintf(stderr, "\t within the extent, which may not be correct!\n"); + fprintf(stderr, "\t Use '-rdem' to set a realistic value\n"); + fprintf(stderr, "\n -- -- ----------------- Source Database ----------------- --\n"); + fprintf(stderr, "-d or --db-path pathname to the SpatiaLite DB\n"); + fprintf(stderr, "-t or --table table_name, must be a SpatialTable\n"); + fprintf(stderr, "-g or --geometry-column the Geometry column to update\n"); + fprintf(stderr, "\t must be a Z or a ZM Dimension type\n\t use CastToXYZ(geom) or CastToXYZM(geom) to convert \n"); + fprintf(stderr, " -- -- --------------- General Parameters ---------------- --\n"); + fprintf(stderr, "-mdem or --copy-m [0=no, 1= yes [default] if exists]\n"); + fprintf(stderr, "-default_srid or --srid for use with -fetchz\n"); + fprintf(stderr, "-fetchz_xy x- and y-value for use with -fetchz\n"); + fprintf(stderr, "-v or --verbose messages during -updatez and -fetchz\n"); + fprintf(stderr, "-save_conf based on active -ddem , -tdem, -gdem and -srid when valid\n"); + fprintf(stderr, "\n -- -- -------------------- Notes: ---------------------- --\n"); + fprintf(stderr, "-I-> the Z value will be copied from the nearest point found\n"); + fprintf(stderr, "-I-> the Srid of the source Geometry and the Dem-POINT can be different\n"); + fprintf(stderr, "-I-> when -fetchz_xy is used in a bash script, -v should not be used\n"); + fprintf(stderr, "\t the z-value will then be retured as the result\n"); + fprintf(stderr, "\n -- -- -------------------- Conf file: ------------------- --\n"); + fprintf(stderr, "-I-> if 'SPATIALITE_DEM' is set with the path to a file\n"); + fprintf(stderr, "-I--> 'export SPATIALITE_DEM=/long/path/to/file/berlin_dhh92.conf'\n"); + fprintf(stderr, "-I-> then '-save_conf' save the config to that file\n"); + fprintf(stderr, "-I-> this file will be read on each application start, setting those values\n"); + fprintf(stderr, "-I--> the parameters for :\n"); + fprintf(stderr, "\t which Dem-Database and Geometry and the default_srid to use for queries\n"); + fprintf(stderr, "\t -> would then not be needed\n"); + fprintf(stderr, "\n -- -- ---------------- Importing .xyz files: ------------------- --\n"); + fprintf(stderr, "-I-> a single xyz.file or a directory containing .xyz files can be given\n"); + fprintf(stderr, "\t for directories: only files with the extension .xyz will be searched for\n"); + fprintf(stderr, "-I-> a single list.file inside a directory containing .xyz files can be given\n"); + fprintf(stderr, "\t each line containing the file-name that must exist in that directory\n"); + fprintf(stderr, "-I-> validty checks are done before importing xyz-files\n"); + fprintf(stderr, "\t the first line may contain only 3 double values (point_x/y/z)\n"); + fprintf(stderr, "\t if valid, the file-name and the point_x/y points are stored\n"); + fprintf(stderr, "\t when importing, the list will be read based of the y/x points\n"); + fprintf(stderr, "\n -- -- ---------------- Sorting .xyz files: ---------------------- --\n"); + fprintf(stderr, "-I-> xyz.files should be sorted:\n"); + fprintf(stderr, "\t y='South to North' and x='West to East': \n"); + fprintf(stderr, "\t sort -n -k2 -k1 input_file.xyz -o output_file.sort.xyz"); + fprintf(stderr, "\n=========================== Commands ===========================\n"); + fprintf(stderr, "-sniff [default] analyse settings without UPDATE of z-values \n"); + fprintf(stderr, "-updatez Perform UPDATE of z-values \n"); + fprintf(stderr, "-fetchz Perform Query of z-values using -fetchz_x_y and default_srid\n"); + fprintf(stderr, "\t will be assumed when using -fetchz_x_y\n"); + fprintf(stderr, "-create_dem create Dem-Database using -ddem,-tdem, -gdem and -srid for the Database \n"); + fprintf(stderr, "\t -d as a dem.xyz file \n"); + fprintf(stderr, "-import_xyz import another .xyz file into a Dem-Database created with -create_dem \n"); + fprintf(stderr, "\t these points will not be sorted, but added to the end "); + fprintf(stderr, "\n=========================== Sample ===========================\n"); + fprintf(stderr, "--> with 'SPATIALITE_DEM' set: \n"); + fprintf(stderr, "spatialite_dem -fetchz_xy 24700.55278283251 20674.74537357586\n"); + fprintf(stderr, "33.5600000 \n"); + fprintf(stderr, "==============================================================\n"); +} +// -- -- ---------------------------------- -- +// Checking the status of the Dem-Database +// - used by differenct command types +// -- -- ---------------------------------- -- +static int +command_check_source_db(sqlite3 *db_handle, struct config_dem*source_config, struct config_dem*dem_config, int verbose) +{ + int ret=0; + int geometry_type=0; + if (strlen(source_config->dem_path) > 0) +// -- -- ---------------------------------- -- + if ((strlen(source_config->dem_path) > 0) && (strlen(source_config->dem_table) > 0) && (strlen(source_config->dem_geometry) > 0)) + { + if (check_geometry_dimension(db_handle,source_config, &geometry_type,verbose)) + { + if (verbose) + { + fprintf(stderr,"Source: srid %d\n", source_config->default_srid); + fprintf(stderr,"Source: extent min x/y(%2.7f,%2.7f)\n\t max x/y(%2.7f,%2.7f)\n", + source_config->dem_extent_minx,source_config->dem_extent_miny, + source_config->dem_extent_maxx,source_config->dem_extent_maxy); + fprintf(stderr,"Source: rows_count(%s) %d\n",source_config->dem_geometry, source_config->dem_rows_count); + fprintf(stderr,"Source: geometry_type(%d) has_z[%d]\n",geometry_type,source_config->has_z); + fprintf(stderr,"Source: spatial_index_enabled[%d]\n",source_config->has_spatial_index); + } + if (source_config->is_spatial_table == 1) + { + if (source_config->has_z) + {// The source Database Table and geometry-columns exists and contains a z-value dimension. + ret = 0; + if (verbose) + { + fprintf(stderr,"Source '%s'\n", source_config->dem_path); + fprintf(stderr," will set %s(%s) Z-Values\n\tfrom nearest POINT found in\n",source_config->dem_table, source_config->dem_geometry); + } + } + else + { + ret = -1; + if (verbose) + { + fprintf(stderr, "DB '%s'\n", source_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] does not contained in a SpatialTable [will not update]\n",source_config->dem_table, source_config->dem_geometry); + fprintf(stderr, "\t command_check_source_db failed: sorry, cowardly quitting\n\n"); + } + } + } + else + { + ret = -1; + if (verbose) + { + fprintf(stderr, "DB '%s'\n", source_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] does not contain a Z-Dimension\n",source_config->dem_table, source_config->dem_geometry); + fprintf(stderr, "\t command_check_source_db failed: sorry, cowardly quitting\n\n"); + } + } + } + else + {// The source Database Table or geometry-columns does not exist. + ret = -1; + if (verbose) + { + fprintf(stderr, "DB '%s'\n", source_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] not found\n",source_config->dem_table, source_config->dem_geometry); + fprintf(stderr, "\t check_geometry_dimension failed: sorry, cowardly quitting\n\n"); + } + } + if (ret == 0) + { + if (verbose) + { + fprintf(stderr, "Source Database: has passed all checks.\n\n"); + } + } + } + else + { + if ((strlen(source_config->dem_path) > 0) && (strcmp(source_config->dem_path,".xyz") != 1)) + { + if (verbose) + { + fprintf(stderr,"-E-> command_check_source_db: preconditions failed for check_source_db [%s(%s)]\n\t source[%s] \n",source_config->dem_table, source_config->dem_geometry,source_config->dem_path); + } + } + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Checking the status of the Dem-Database +// - used by differenct command types +// -- -- ---------------------------------- -- +static int +command_check_dem_db(sqlite3 *db_handle, struct config_dem*dem_config, struct config_dem*source_config, int verbose) +{ + int ret=0; + double resolution_calc=0.0; + double resolution_dem=dem_config->dem_resolution; + int geometry_type=0; +// -- -- ---------------------------------- -- + if ((strlen(dem_config->dem_path) > 0) && (strlen(dem_config->dem_table) > 0) && (strlen(dem_config->dem_geometry) > 0)) + { + if (check_geometry_dimension(db_handle,dem_config, &geometry_type, verbose)) + { + if (dem_config->dem_rows_count) + { + resolution_calc=(dem_config->dem_extent_maxx-dem_config->dem_extent_minx)*(dem_config->dem_extent_maxy-dem_config->dem_extent_miny)/(double)dem_config->dem_rows_count; + } + if (verbose) + { + fprintf(stderr,"Dem: srid %d\n", dem_config->dem_srid); + fprintf(stderr,"Dem: extent min x/y(%2.7f,%2.7f)\n\t max x/y(%2.7f,%2.7f)\n", + dem_config->dem_extent_minx,dem_config->dem_extent_miny, + dem_config->dem_extent_maxx,dem_config->dem_extent_maxy); + fprintf(stderr,"Dem: extent width(%2.7f)\n\t height(%2.7f)\n", + (dem_config->dem_extent_maxx-dem_config->dem_extent_minx), + (dem_config->dem_extent_maxy-dem_config->dem_extent_miny)); + fprintf(stderr,"Dem: rows_count(%s) %u\n",dem_config->dem_geometry, dem_config->dem_rows_count); + fprintf(stderr,"Dem: resolution(%s) %2.7f\n",dem_config->dem_geometry, resolution_calc); + fprintf(stderr,"Dem: geometry_type(%d) has_z[%d] has_m[%d]\n",geometry_type,dem_config->has_z, dem_config->has_m); + fprintf(stderr,"Dem: spatial_index_enabled[%d]\n",dem_config->has_spatial_index); + } + if (dem_config->has_z) + {// The dem Database Table and geometry-columns exist and contains a z-value dimension. + switch (geometry_type) + { + case GAIA_POINTZ: + case GAIA_POINTZM: + { + if (dem_config->has_spatial_index == 1) + { + if ( (source_config) && (strlen(source_config->dem_path) > 0) && (strlen(source_config->dem_table) > 0)) + {// No printing when .xyz file + if (verbose) + { + fprintf(stderr,"Source '%s'\n", source_config->dem_path); + fprintf(stderr," will set %s(%s) Z-Values\n\tfrom nearest POINT found in\n",source_config->dem_table, source_config->dem_geometry); + } + } + if (verbose) + { + fprintf(stderr,"Dem '%s'\n", dem_config->dem_path); + fprintf(stderr," TABLE[%s] with GEOMETRY-Column[%s]\n",dem_config->dem_table, dem_config->dem_geometry); + } + ret = 0; + } + else + { + if (verbose) + { + fprintf(stderr, "Dem '%s'\n", dem_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] must be a POINT with a Z-Dimension with a SpatialIndex\n",dem_config->dem_table, dem_config->dem_geometry); + fprintf(stderr, "\t command_check_dem_db failed: sorry, cowardly quitting\n\n"); + } + ret = -1; + } + } + break; + default: + if (verbose) + { + fprintf(stderr, "Dem '%s'\n", dem_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] must be a POINT with a Z-Dimension\n",dem_config->dem_table, dem_config->dem_geometry); + fprintf(stderr, "\t command_check_dem_db failed: sorry, cowardly quitting\n\n"); + } + ret = -1; + break; + } + } + else + { + if (verbose) + { + fprintf(stderr, "Dem '%s'\n", dem_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] does not contain a Z-Dimension\n",dem_config->dem_table, dem_config->dem_geometry); + fprintf(stderr, "\t command_check_dem_db failed: sorry, cowardly quitting\n\n"); + } + ret = -1; + } + } + else + {// The dem Database Table or geometry-columns does not exist. + if (verbose) + { + fprintf(stderr, "Dem '%s'\n", dem_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] not found\n",dem_config->dem_table, dem_config->dem_geometry); + fprintf(stderr, "\t check_geometry_dimension failed: sorry, cowardly quitting\n\n"); + } + ret = -1; + } + if (ret == 0) + { + if (resolution_dem <= 0.0) + { + if (verbose) + { + fprintf(stderr, "-W-> -rdem was not set. Using: resolution(%s) %2.7f\n",dem_config->dem_geometry, resolution_calc); + } + resolution_dem=resolution_calc; + } + else + { + if (verbose) + { + fprintf(stderr, "-W-> -rdem was set. Using: resolution(%2.7f), overriding the calculated value: %2.7f\n",resolution_dem, resolution_calc); + } + } + dem_config->dem_resolution=resolution_dem; + if ((source_config) && (source_config->has_z)) + { + dem_config->default_srid=source_config->default_srid; + if (verbose) + { + if (dem_config->dem_srid == source_config->default_srid) + { + fprintf(stderr, "Dem srid[%d]: is the same as the Source srid[%d].\n", dem_config->dem_srid,dem_config->default_srid); + if ( ( source_config->dem_extent_minx >= dem_config->dem_extent_minx ) && (source_config->dem_extent_maxx <= dem_config->dem_extent_maxx ) && + ( source_config->dem_extent_miny >= dem_config->dem_extent_miny ) && (source_config->dem_extent_maxy <= dem_config->dem_extent_maxy ) ) + { + fprintf(stderr, "The Source[%s]: is totally within the Dem[%s] area.\n", source_config->dem_geometry,dem_config->dem_geometry); + } + else if ( ( source_config->dem_extent_minx < dem_config->dem_extent_minx ) && (source_config->dem_extent_maxx > dem_config->dem_extent_maxx ) && + ( source_config->dem_extent_miny < dem_config->dem_extent_miny ) && (source_config->dem_extent_maxy > dem_config->dem_extent_maxy ) ) + { + fprintf(stderr, "The Source[%s]: is totally covers the Dem[%s] area.\n", source_config->dem_geometry,dem_config->dem_geometry); + fprintf(stderr, "\t only geometries totally within the Dem area will be updated.\n"); + } + else if ( ( ( source_config->dem_extent_minx < dem_config->dem_extent_minx ) || ( source_config->dem_extent_minx > dem_config->dem_extent_maxx ) ) && + ( ( source_config->dem_extent_maxx > dem_config->dem_extent_maxx ) || ( source_config->dem_extent_maxx < dem_config->dem_extent_minx ) ) && + ( ( source_config->dem_extent_miny < dem_config->dem_extent_miny ) || (source_config->dem_extent_miny > dem_config->dem_extent_maxy) ) && + ( ( source_config->dem_extent_maxy > dem_config->dem_extent_maxy ) || ( source_config->dem_extent_maxy < dem_config->dem_extent_miny ) ) ) + { + // ?? correct ?? + fprintf(stderr, "The Dem[%s]: is totally outside of the Source[%s] area.\n", dem_config->dem_geometry,source_config->dem_geometry); + } + else + { + fprintf(stderr, "The Source[%s]: is partially inside of the Dem[%s] area.\n", source_config->dem_geometry,dem_config->dem_geometry); + } + } + else + { + fprintf(stderr, "Dem default_srid[%d]: is different from the Source default_srid[%d].\n", dem_config->dem_srid,dem_config->default_srid); + fprintf(stderr, "\t When searching for the nearest point, the Source points will be transformed to srid[%d].\n", dem_config->dem_srid); + } + fprintf(stderr, "Dem Database: has passed all checks.\n"); + } + } + } + } + else + { + if (strlen(dem_config->dem_path) > 0) + { + if (verbose) + { + fprintf(stderr,"-E-> command_check_dem_db: preconditions failed [%s(%s)] \n",dem_config->dem_table, dem_config->dem_geometry); + } + } + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Implementation of command: updatez +// - from a Table, geometry of Dem +// --> update each z value with z value of +// --> nearest Point of Dem +// -- -- ---------------------------------- -- +static int +command_updatez_db(sqlite3 *db_handle, struct config_dem*source_config, struct config_dem*dem_config, int verbose) +{ + int ret=0; + char *time_message = NULL; + struct timeval time_start; + struct timeval time_end; + struct timeval time_diff; + char *sql_err = NULL; + int count_total_geometries=0; + int count_changed_geometries=0; + int count_points_total=0; + int count_z_total=0; + int count_m_total=0; + + if ((strlen(dem_config->dem_path) > 0) && (strlen(dem_config->dem_table) > 0) && (strlen(dem_config->dem_geometry) > 0) && + (dem_config->dem_srid > 0) && (dem_config->has_z) && + (strlen(source_config->dem_path) > 0) && (strlen(source_config->dem_table) > 0) && (strlen(source_config->dem_geometry) > 0) && + (source_config->default_srid > 0) && (source_config->has_z)) + {// The dem Database Table and geometry-columns exist and contains a z-value dimension. + // -- -- ---------------------------------- -- + if (verbose) + { + fprintf(stderr,"-I-> starting update of [%s(%s)] where Z-Values are different.\n",source_config->dem_table, source_config->dem_geometry); + } + /* ok, going to convert */ + /* the complete operation is handled as an unique SQL Transaction */ + gettimeofday(&time_start, 0); + if (sqlite3_exec(db_handle, "BEGIN", NULL, NULL, &sql_err) == SQLITE_OK) + { + if (retrieve_geometries(db_handle, source_config, dem_config, &count_total_geometries,&count_changed_geometries,&count_points_total,&count_z_total,&count_m_total, verbose) ) + { + /* committing the pending SQL Transaction */ + if (sqlite3_exec(db_handle, "COMMIT", NULL, NULL, &sql_err) == SQLITE_OK) + { + ret = 0; + } + else + { + if (verbose) + { + fprintf(stderr, "COMMIT TRANSACTION error: %s\n", sql_err); + } + sqlite3_free(sql_err); + if (sql_err) + { + sqlite3_free(sql_err); + } + ret = -1; + } + } + else + { + ret = -1; + if (sqlite3_exec(db_handle, "ROLLBACK", NULL, NULL, &sql_err) == SQLITE_OK) + { + } + if (sql_err) + { + sqlite3_free(sql_err); + } + if (verbose) + { + fprintf(stderr, "DB '%s'\n", source_config->dem_path); + fprintf(stderr, "TABLE[%s] or GEOMETRY-Column[%s] error durring UPDATE\n",source_config->dem_table, source_config->dem_geometry); + fprintf(stderr, "*** ERROR: conversion failed\n\n"); + } + } + gettimeofday(&time_end, 0); + timeval_subtract(&time_diff,&time_end,&time_start,&time_message); + if (ret == 0) + { + if (verbose) + { + fprintf(stderr,"-I-> geometries total[%d] changed[%d] ; points total[%d] changed z[%d] changed m[%d]\n",count_total_geometries,count_changed_geometries,count_points_total,count_z_total,count_m_total); + fprintf(stderr,"\tDatabase-file successfully updated found, changed, Z-Values !!!\n"); + fprintf(stderr,"%s\n\n", time_message); + } + } + } + else + { + if (verbose) + { + fprintf(stderr, "BEGIN TRANSACTION error: %s\n", sql_err); + } + sqlite3_free(sql_err); + if (sql_err) + { + sqlite3_free(sql_err); + } + ret = -1; + } + } + else + {// preconditions not fulfilled + if (verbose) + { + fprintf(stderr,"-E-> command_updatez_db: preconditions failed [%s(%s)] \n",source_config->dem_table, source_config->dem_geometry); + } + } +// -- -- ---------------------------------- -- + if (time_message) + { + sqlite3_free(time_message); + time_message = NULL; + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Implementation of command: fetchz +// - from a given srid, point_x,point_y +// --> return point_z value +// -- -- ---------------------------------- -- +static int +command_fetchz(sqlite3 *db_handle, struct config_dem *dem_config, int verbose) +{ + int ret=0; + char *time_message = NULL; + struct timeval time_start; + struct timeval time_end; + struct timeval time_diff; +// -- -- ---------------------------------- -- + if ( (dem_config->fetchz_x != 0.0) && (dem_config->fetchz_x != dem_config->fetchz_y) && (dem_config->default_srid > 0) && (dem_config->dem_srid > 0)) + { + if (verbose) + { + fprintf(stderr, "FetchZ modus: with default_srid[%d] x[%2.7f] y[%2.7f] has_m[%d]\n",dem_config->default_srid,dem_config->fetchz_x,dem_config->fetchz_y,dem_config->has_m); + } + gettimeofday(&time_start, 0); + if (callFetchZ(db_handle,dem_config,verbose) ) + { + ret=1; + gettimeofday(&time_end, 0); + timeval_subtract(&time_diff,&time_end,&time_start,&time_message); + if (verbose) + { + if (dem_config->has_m) + { + fprintf(stderr, "FetchZ modus: with dem_srid[%d] x[%2.7f] y[%2.7f] z[%2.7f] m[%2.7f]\n",dem_config->dem_srid,dem_config->fetchz_x,dem_config->fetchz_y,dem_config->dem_z,dem_config->dem_m); + fprintf(stderr,"%s\n", time_message); + } + else + { + fprintf(stderr, "FetchZ modus: with dem_srid[%d] x[%2.7f] y[%2.7f] z[%2.7f]\n",dem_config->dem_srid,dem_config->fetchz_x,dem_config->fetchz_y,dem_config->dem_z); + fprintf(stderr,"%s\n", time_message); + } + } + else + {// Output for bash + if (dem_config->has_m) + { + printf("%2.7f %2.7f\n", dem_config->dem_z,dem_config->dem_m); + } + else + { + printf("%2.7f\n", dem_config->dem_z); + } + } + } + else + { + // callFetchZ failed + } + } + else + { + // preconditions failed + if (verbose) + { + if ( dem_config->fetchz_x == 0.0) + { + fprintf(stderr, "did you forget setting the -fetchz_x argument ?\n"); + } + if ( dem_config->fetchz_y == 0.0) + { + fprintf(stderr, "did you forget setting the -fetchz_y argument ?\n"); + } + if ( dem_config->default_srid <= 0) + { + fprintf(stderr, "did you forget setting the -default_srid argument ?\n"); + } + if ( dem_config->dem_srid <= 0) + { + fprintf(stderr, "The dem-srid is invalid\n"); + } + fprintf(stderr, "-E command_fetchz: sorry, cowardly quitting\n\n"); + } + } +// -- -- ---------------------------------- -- + if (time_message) + { + sqlite3_free(time_message); + time_message = NULL; + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Implementation of command: fetchz +// - from a given srid, point_x,point_y +// --> return point_z value +// -- -- ---------------------------------- -- +static int +command_dem_create(sqlite3 **db_handle, void *cache, struct config_dem *source_config, struct config_dem *dem_config, int verbose) +{ + int ret=0; + char *time_message = NULL; + struct timeval time_start; + struct timeval time_end; + struct timeval time_diff; + int count_xyz_files=0; +// -- -- ---------------------------------- -- + if (cache) + { + if ( dem_config->dem_srid <= 0) + { + dem_config->dem_srid=dem_config->default_srid; + } + if ((strlen(dem_config->dem_path) > 0) && (strlen(dem_config->dem_table) > 0) && (strlen(dem_config->dem_geometry) > 0) && (dem_config->dem_srid > 0)) + { + gettimeofday(&time_start, 0); + if (create_dem_db(dem_config->dem_path, db_handle, cache, dem_config->dem_table, dem_config->dem_geometry,verbose)) + { + if (verbose) + { + fprintf(stderr,"-I-> command_dem_createt: created [%s] \n", dem_config->dem_path); + } + if (collect_xyz_files(*db_handle,source_config->dem_path, &count_xyz_files, 0) == 1) + { + dem_config->dem_rows_count=0; + if (import_xyz(*db_handle, dem_config,count_xyz_files,verbose)) + {// Import completed correctly + gettimeofday(&time_end, 0); + timeval_subtract(&time_diff,&time_end,&time_start,&time_message); + if (verbose) + { + fprintf(stderr,"%s\n", time_message); + } + gettimeofday(&time_start, 0); + if (recover_geometry_dem(*db_handle, dem_config,verbose)) + {// Task completed correctly + } + else + {// Task failed + if (verbose) + { + fprintf(stderr,"-W-> command_dem_created: recover_geometry_dem failed [%s(%s)] srid[%d] \n", dem_config->dem_table, dem_config->dem_geometry, dem_config->dem_srid); + } + } + // Sniff the results, set schema_dem to 'main' + dem_config->schema=source_config->schema; + source_config->schema=NULL; + gettimeofday(&time_end, 0); + timeval_subtract(&time_diff,&time_end,&time_start,&time_message); + if (verbose) + { + fprintf(stderr,"%s\n", time_message); + } + } + else + {// Import failed + if (verbose) + { + fprintf(stderr,"-W-> command_dem_created: import_xyz failed [%d] [%s] \n", count_xyz_files,source_config->dem_path); + } + } + } + } + else + { + // Database exits or cannot be created + if (verbose) + { + fprintf(stderr, "Dem '%s'\n", dem_config->dem_path); + fprintf(stderr, "Database exists and will not be overwritten, use -import_xyz to add new data\n"); + fprintf(stderr, "-E-> command_dem_create: sorry, cowardly quitting\n\n"); + } + } + } + else + { + // preconditions failed + if (verbose) + { + if (strlen(dem_config->dem_path) <= 0) + { + fprintf(stderr, "did you forget setting the -ddem argument ?\n"); + } + if (strlen(dem_config->dem_table) <= 0) + { + fprintf(stderr, "did you forget setting the -tdem argument ?\n"); + } + if (strlen(dem_config->dem_geometry) <= 0) + { + fprintf(stderr, "did you forget setting the -gdem argument ?\n"); + } + if ( dem_config->default_srid <= 0) + { + fprintf(stderr, "did you forget setting the -default_srid argument ?\n"); + } + if ( dem_config->dem_srid <= 0) + { + fprintf(stderr, "The dem-srid is invalid\n"); + } + fprintf(stderr, "-E command_fetchz: sorry, cowardly quitting\n\n"); + } + } + } +// -- -- ---------------------------------- -- + if (time_message) + { + sqlite3_free(time_message); + time_message = NULL; + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Implementation of command: -import_xyz +// - from a given srid, point_x,point_y +// --> return point_z value +// -- -- ---------------------------------- -- +static int +command_import_xyz(sqlite3 *db_handle, struct config_dem *source_config, struct config_dem *dem_config, int verbose) +{ + int ret=0; + char *time_message = NULL; + char *sql_statement = NULL; + char *err_msg = NULL;; + struct timeval time_start; + struct timeval time_end; + struct timeval time_diff; + int count_xyz_files=0; +// -- -- ---------------------------------- -- + if ((strlen(source_config->dem_path) > 0) && (strlen(dem_config->dem_path) > 0) && (strlen(dem_config->dem_table) > 0) && (strlen(dem_config->dem_geometry) > 0)) + { + if ((dem_config->has_z) && (dem_config->dem_srid > 0)) + { + if (db_handle) + { + gettimeofday(&time_start, 0); + if (verbose) + { + fprintf(stderr, "-import_xyz: with srid[%d] .xyz[%s] \n",source_config->default_srid,source_config->dem_path); + } + if (collect_xyz_files(db_handle,source_config->dem_path, &count_xyz_files, 0) == 1) + { + dem_config->dem_rows_count=0; // Set to 0, just in case + if (import_xyz(db_handle, dem_config,count_xyz_files,verbose)) + {// Import completed correctly + gettimeofday(&time_end, 0); + timeval_subtract(&time_diff,&time_end,&time_start,&time_message); + if (verbose) + { + fprintf(stderr,"%s\n", time_message); + } + gettimeofday(&time_start, 0); + if (verbose) + { + fprintf(stderr,"UpdateLayerStatistics: %s(%s)\n", dem_config->dem_table,dem_config->dem_geometry); + } + sql_statement = sqlite3_mprintf("SELECT UpdateLayerStatistics(%Q, %Q)", dem_config->dem_table,dem_config->dem_geometry); + int ret_update = sqlite3_exec(db_handle, sql_statement, NULL, NULL, &err_msg); + sqlite3_free(sql_statement); + if (ret_update != SQLITE_OK) + { + fprintf(stderr, "UpdateLayerStatistics error: %s\n", err_msg); + sqlite3_free(err_msg); + } + else + { + ret=1; + } + gettimeofday(&time_end, 0); + timeval_subtract(&time_diff,&time_end,&time_start,&time_message); + if (verbose) + { + fprintf(stderr,"%s\n", time_message); + } + } + } + } + } + } +// -- -- ---------------------------------- -- + if (time_message) + { + sqlite3_free(time_message); + time_message = NULL; + } +// -- -- ---------------------------------- -- + return ret; +} +// -- -- ---------------------------------- -- +// Main +// Commands +// - sniff +// -> allows the user to prepair the 'update' command +// -> Source and Dem can be done separately or together +// - update +// -- -- ---------------------------------- -- +int +main(int argc, char *argv[]) +{ + /* the MAIN function simply perform arguments checking */ + sqlite3 *db_handle = NULL; + char *schema_db = "main"; + char *schema_dem = "db_dem"; + char *dem_geometry_default = "dem_point"; + void *cache = NULL; + int verbose=0; + int copy_m = 1; + int next_arg = ARG_NONE; + int i_command_type=CMD_DEM_SNIFF; + struct config_dem dem_config; + struct config_dem source_config; + int save_conf=0; + int exit_code=1; // unix_exit_code: 0=correct, 1=error + int i=0; + int error = 0; +// -- -- ---------------------------------- -- +// Will look for conf [not an error if nothing found] +// - if not found, all arguments must be set +// -- -- ---------------------------------- -- + char *dem_configfile = "spatialite_dem.conf"; + char *spatialite_dem = getenv("SPATIALITE_DEM"); +// -- -- ---------------------------------- -- +// Reading the configuration, if found +// - setting default values +// -- -- ---------------------------------- -- + if (spatialite_dem) + { + dem_configfile=spatialite_dem; + } +// -- -- ---------------------------------- -- +// Warning, if non default, conf is given but not found +// -- -- ---------------------------------- -- + dem_config = get_demconfig(dem_configfile,1); + dem_config.config_type = CONF_TYPE_DEM; // dem + dem_config.schema = schema_dem; // dem +// -- -- ---------------------------------- -- +// No external source config +// - returns default values only +// -- -- ---------------------------------- -- + source_config = get_demconfig(NULL,0); + source_config.config_type = CONF_TYPE_SOURCE; // source + source_config.schema = schema_db; // source +// -- -- ---------------------------------- -- + if (strlen(dem_config.dem_path) > 0) + { + if (dem_config.dem_srid > 0) + { + source_config.dem_srid=dem_config.dem_srid; + } + if (dem_config.default_srid > 0) + { + source_config.default_srid=dem_config.default_srid; + } + } +// -- -- ---------------------------------- -- +// Reading the arguments +// -- -- ---------------------------------- -- + for (i = 1; i < argc; i++) + { + // parsing the invocation arguments + if (next_arg != ARG_NONE) + { + switch (next_arg) + { + case ARG_DB_PATH: + strcpy(source_config.dem_path,argv[i]); + break; + case ARG_TABLE: + strcpy(source_config.dem_table,argv[i]); + break; + case ARG_COL: + strcpy(source_config.dem_geometry,argv[i]); + break; + case ARG_DEM_PATH: + strcpy(dem_config.dem_path,argv[i]); + break; + case ARG_TABLE_DEM: + strcpy(dem_config.dem_table,argv[i]); + break; + case ARG_COL_DEM: + strcpy(dem_config.dem_geometry,argv[i]); + break; + case ARG_RESOLUTION_DEM: + // this will override the calculated value (which may not be correct) + // - it also gives the user the choice to change the area around a point to search for. + dem_config.dem_resolution = atof(argv[i]); + break; + case ARG_COPY_M: + copy_m = atoi(argv[i]); + if (copy_m != 1 ) + copy_m=0; + break; + case ARG_FETCHZ_X: + dem_config.fetchz_x = atof(argv[i]); + break; + case ARG_FETCHZ_Y: + dem_config.fetchz_y = atof(argv[i]); + break; + case ARG_FETCHZ_XY: + dem_config.fetchz_x = atof(argv[i++]); + dem_config.fetchz_y = atof(argv[i]); + break; + case ARG_DEFAULT_SRID: + source_config.default_srid = atoi(argv[i]); + dem_config.default_srid = atoi(argv[i]); + break; + }; + next_arg = ARG_NONE; + continue; + } + if (strcasecmp (argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) + { + do_help (); + return exit_code; + } + if (strcmp(argv[i], "-d") == 0) + { + next_arg = ARG_DB_PATH; + continue; + } + if (strcasecmp (argv[i], "--db-path") == 0) + { + next_arg = ARG_DB_PATH; + continue; + } + if (strcasecmp (argv[i], "--table") == 0) + { + next_arg = ARG_TABLE; + continue; + } + if (strcmp(argv[i], "-t") == 0) + { + next_arg = ARG_TABLE; + continue; + } + if (strcasecmp (argv[i], "--geometry-column") == 0) + { + next_arg = ARG_COL; + continue; + } + if (strcmp(argv[i], "-g") == 0) + { + next_arg = ARG_COL; + continue; + } + if (strcasecmp (argv[i], "--dem-path") == 0) + { + next_arg = ARG_DEM_PATH; + continue; + } + if (strcmp(argv[i], "-ddem") == 0) + { + next_arg = ARG_DEM_PATH; + continue; + } + if (strcasecmp (argv[i], "--table-dem") == 0) + { + next_arg = ARG_TABLE_DEM; + continue; + } + if (strcmp(argv[i], "-tdem") == 0) + { + next_arg = ARG_TABLE_DEM; + continue; + } + if (strcasecmp (argv[i], "--geometry-dem-column") == 0) + { + next_arg = ARG_COL_DEM; + continue; + } + if (strcmp(argv[i], "-gdem") == 0) + { + next_arg = ARG_COL_DEM; + continue; + } + if (strcasecmp (argv[i], "--dem-resolution") == 0) + { + next_arg = ARG_RESOLUTION_DEM; + continue; + } + if (strcmp(argv[i], "-rdem") == 0) + { + next_arg = ARG_RESOLUTION_DEM; + continue; + } + if (strcasecmp (argv[i], "--m-copy") == 0) + { + next_arg = ARG_COPY_M; + continue; + } + if (strcmp(argv[i], "-mdem") == 0) + { + next_arg = ARG_COPY_M; + continue; + } + if (strcmp(argv[i], "-sniff") == 0) + { + i_command_type=CMD_DEM_SNIFF; + continue; + } + if (strcmp(argv[i], "-updatez") == 0) + { + i_command_type=CMD_DEM_UPDATEZ; + continue; + } + if (strcmp(argv[i], "-fetchz") == 0) + { + i_command_type=CMD_DEM_FETCHZ; + continue; + } + if (strcmp(argv[i], "-create_dem") == 0) + { + i_command_type=CMD_DEM_CREATE; + continue; + } + if (strcmp(argv[i], "-import_xyz") == 0) + { + i_command_type=CMD_DEM_IMPORT_XYZ; + continue; + } + if (strcmp(argv[i], "-fetchz_x") == 0) + { + next_arg = ARG_FETCHZ_X; + continue; + } + if (strcmp(argv[i], "-fetchz_y") == 0) + { + next_arg = ARG_FETCHZ_Y; + continue; + } + if (strcmp(argv[i], "-fetchz_xy") == 0) + { + next_arg = ARG_FETCHZ_XY; + continue; + } + if ( (strcmp(argv[i], "-default_srid") == 0) || (strcmp(argv[i], "--srid") == 0) ) + { + next_arg = ARG_DEFAULT_SRID; + continue; + } + if ( (strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--verbose") == 0) ) + { + verbose = 1; + continue; + } + if ( (strcmp(argv[i], "-save_conf") == 0) || (strcmp(argv[i], "--dem_conf") == 0) ) + { + save_conf=1; + continue; + } + fprintf(stderr, "unknown argument: %s\n", argv[i]); + error = 1; + } +// -- -- ---------------------------------- -- +// Setting the default argument of dem_geometry +// - dem_point +// -- -- ---------------------------------- -- + if (strlen(dem_config.dem_geometry) == 0) + { + strcpy(dem_config.dem_geometry,dem_geometry_default); + } +// -- -- ---------------------------------- -- +// checking, resetting the arguments +// -- -- ---------------------------------- -- + if (i_command_type == CMD_DEM_SNIFF) + { + if ((strlen(dem_config.dem_path) > 0) && (strlen(dem_config.dem_table) > 0) && (strlen(dem_config.dem_geometry) > 0) && + (dem_config.fetchz_x != 0.0) && (dem_config.fetchz_x != dem_config.fetchz_y) ) + {// -fetchz was intended but forgotten, be tolerant to the lazy user + i_command_type = CMD_DEM_FETCHZ; + } + else + {// for -sniff -v is always active + verbose=1; + } + } + if (verbose) + { + if (strlen(dem_config.dem_path) == 0) + { + if (i_command_type == CMD_DEM_UPDATEZ) + { + fprintf(stderr, "did you forget setting the --dem-path argument ?\n"); + error = 1; + } + else + { + fprintf(stderr, "Warning: --dem-path argument has not been set [assuming -sniff only]\n"); + } + } + if (strlen(source_config.dem_path) == 0) + { + if (i_command_type == CMD_DEM_UPDATEZ) + { + fprintf(stderr, "did you forget setting the --db-path argument ?\n"); + error = 1; + } + } + } +// -- -- ---------------------------------- -- +// Bale out on errors +// -- -- ---------------------------------- -- + if (error) + { + do_help(); + return exit_code; + } +// -- -- ---------------------------------- -- +// opening the DB +// - method 1: create a new Database +// - method 2: input is not a Database, only Dem +// - method 3: both input and dem are a Database, when given +// -- -- ---------------------------------- -- + cache = spatialite_alloc_connection(); + if (i_command_type == CMD_DEM_CREATE) + { + if (command_dem_create(&db_handle, cache, &source_config, &dem_config, verbose)) + { + // Sniff the results, set schema_dem to 'main' + i_command_type = CMD_DEM_SNIFF; + dem_config.schema=schema_db; + } + } + else + { + if (i_command_type == CMD_DEM_IMPORT_XYZ) + {// Open the Dem-Database as the main source [not attached ; since db_path=import.xyz] + open_db(&db_handle, cache, NULL, &dem_config,verbose); + } + else + {// Open the Dem-Database as the main source if there is no source [otherwise attached, with source as main ] + open_db(&db_handle, cache, &source_config, &dem_config,verbose); + } + } +// -- -- ---------------------------------- -- +// Bale out if no connection +// -- -- ---------------------------------- -- + if (!db_handle) + { + spatialite_cleanup_ex(cache); + cache=NULL; + return exit_code; + } +// -- -- ---------------------------------- -- +// checking the Source-Database +// -- -- ---------------------------------- -- + command_check_source_db(db_handle,&source_config, &dem_config, verbose); +// -- -- ---------------------------------- -- +// checking the Dem-Database +// -- -- ---------------------------------- -- + if (command_check_dem_db(db_handle,&dem_config, &source_config, verbose) ) + { + if ( save_conf == 1) + { + if (write_demconfig(dem_configfile, dem_config)) + { + fprintf(stderr, "Dem-conf: with default_srid[%d] was saved to\n\t[%s].\n",dem_config.default_srid,dem_configfile); + } + } + } +// -- -- ---------------------------------- -- +// After checking, the called functions +// will check the result before running +// -- -- ---------------------------------- -- + if ( (i_command_type == CMD_DEM_SNIFF) && (dem_config.has_z) && (source_config.has_z)) + { + if (verbose) + { + fprintf(stderr, "Sniffing modus: All pre-conditions have been fulfilled.\n"); + fprintf(stderr, "\t to start update, use the '-updatez' parameter.\n"); + fprintf(stderr, "\t to save dem-conf, use the '-save_conf' parameter.\n"); + } + exit_code = 0; // correct + } +// -- -- ---------------------------------- -- +// Start --update +// -- -- ---------------------------------- -- + if (i_command_type == CMD_DEM_UPDATEZ) + { + if (!copy_m) + {// The User desires that m values be ignored + dem_config.has_m=0; + } + if (command_updatez_db(db_handle, &source_config,&dem_config, verbose) ) + { + exit_code = 0; // correct + } + } +// -- -- ---------------------------------- -- +// Start -import_xyz +// -- -- ---------------------------------- -- + if (i_command_type == CMD_DEM_IMPORT_XYZ) + { + if (command_import_xyz(db_handle, &source_config, &dem_config, verbose)) + { + exit_code = 0; // correct + } + } +// -- -- ---------------------------------- -- +// Start -fetchz +// -- -- ---------------------------------- -- + if (i_command_type == CMD_DEM_FETCHZ) + { + if (command_fetchz(db_handle, &dem_config, verbose) ) + { + exit_code = 0; // correct + } + } +// -- -- ---------------------------------- -- +// Close Application +// - DETACH when needed +// -- -- ---------------------------------- -- + if (db_handle) + { + close_db(db_handle,cache, schema_dem); + cache=NULL; + } + return exit_code; +// -- -- ---------------------------------- -- +} + Index: spatialite_dxf.c ================================================================== --- spatialite_dxf.c +++ spatialite_dxf.c @@ -32,11 +32,15 @@ #include #include #include +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else #include "config.h" +#endif #ifdef SPATIALITE_AMALGAMATION #include #else #include @@ -90,19 +94,32 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_dxf: %s\n", VERSION); + fprintf (stderr, "target CPU ...: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite : %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ...: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -109,10 +126,11 @@ fprintf (stderr, "\n\nusage: spatialite_dxf ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite DB path\n"); fprintf (stderr, "-x or --dxf-path pathname the input DXF path\n\n"); fprintf (stderr, "you can specify the following options as well:\n"); fprintf (stderr, "----------------------------------------------\n"); @@ -214,10 +232,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcasecmp (argv[i], "--db-path") == 0) { next_arg = ARG_DB_PATH; continue; Index: spatialite_gml.c ================================================================== --- spatialite_gml.c +++ spatialite_gml.c @@ -589,10 +589,12 @@ if (params->is_fid) { *(params->CharData + params->CharDataLen) = '\0'; column_name (params, el); } + *(params->CharData) = '\0'; + params->CharDataLen = 0; } static void column_value (struct gml_params *params, const char *el) { @@ -1257,10 +1259,12 @@ } if (strcasecmp (el, "gml:coordinates") == 0) parse_coords_1 (params); if (strcasecmp (el, "gml:posList") == 0 || strcasecmp (el, "gml:pos") == 0) parse_coords_2 (params); + *(params->CharData) = '\0'; + params->CharDataLen = 0; } static void spatialite_autocreate (sqlite3 * db) { @@ -1290,15 +1294,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -1574,10 +1578,27 @@ } if (params->CharData) free (params->CharData); clean_geometry (params); } + +static void +do_version () +{ +/* printing version infos */ + XML_Expat_Version expat; + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_gml: %s\n", VERSION); + fprintf (stderr, "target CPU ...: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite : %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ...: %s\n", sqlite3_libversion ()); + expat = XML_ExpatVersionInfo (); + fprintf (stderr, "libexpat .....: %d.%d.%d\n", expat.major, expat.minor, + expat.micro); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -1584,10 +1605,11 @@ fprintf (stderr, "\n\nusage: spatialite_gml ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-g or --gml-path pathname the GML-XML file path\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite DB path\n\n"); fprintf (stderr, "-t or --table-name name the DB table name\n\n"); fprintf (stderr, "you can specify the following options as well\n"); @@ -1638,10 +1660,11 @@ params.polygon.first = NULL; params.polygon.last = NULL; params.CharDataStep = 65536; params.CharDataMax = params.CharDataStep; params.CharData = malloc (params.CharDataStep); + params.CharDataLen = 0; for (i = 1; i < argc; i++) { /* parsing the invocation arguments */ if (next_arg != ARG_NONE) @@ -1664,10 +1687,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-g") == 0) { next_arg = ARG_GML_PATH; continue; Index: spatialite_network.c ================================================================== --- spatialite_network.c +++ spatialite_network.c @@ -1108,15 +1108,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -2548,10 +2548,23 @@ fprintf (stderr, "sqlite3_close() error: %s\n", sqlite3_errmsg (handle)); spatialite_cleanup_ex (cache); graph_free (p_graph); } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_network: %s\n", VERSION); + fprintf (stderr, "target CPU .......: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite ....: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 .......: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -2558,10 +2571,11 @@ fprintf (stderr, "\n\nusage: spatialite_network ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite db path\n"); fprintf (stderr, "-T or --table table_name the db table to be validated\n"); fprintf (stderr, @@ -2596,11 +2610,11 @@ "1 means that the arc connection in the given direction is\n"); fprintf (stderr, "valid, otherwise 0 means a forbidden connection\n\n"); fprintf (stderr, "in order to create a permanent NETWORK-DATA table\n"); fprintf (stderr, "you can select the following options:\n"); fprintf (stderr, "-o or --output-table table_name\n"); - fprintf (stderr, "-v or --virtual-table table_name\n"); + fprintf (stderr, "-vt or --virtual-table table_name\n"); fprintf (stderr, "--overwrite-output\n\n"); } int main (int argc, char *argv[]) @@ -2670,10 +2684,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcasecmp (argv[i], "--db-path") == 0) { next_arg = ARG_DB_PATH; continue; @@ -2706,11 +2726,11 @@ if (strcasecmp (argv[i], "--virtual-table") == 0) { next_arg = ARG_VIRT_TABLE; continue; } - if (strcmp (argv[i], "-v") == 0) + if (strcmp (argv[i], "-vt") == 0) { next_arg = ARG_VIRT_TABLE; continue; } if (strcasecmp (argv[i], "--from-column") == 0) Index: spatialite_osm_filter.c ================================================================== --- spatialite_osm_filter.c +++ spatialite_osm_filter.c @@ -252,36 +252,48 @@ sqlite3_column_text (query, 9)); if (first) { /* first NODE row */ - char *timestamp = clean_xml (p_timestamp); - char *changeset = clean_xml (p_changeset); - char *user = NULL; - if (p_user) - user = clean_xml (p_user); + char *timestamp = + p_timestamp ? clean_xml (p_timestamp) : + NULL; + char *changeset = + p_changeset ? clean_xml (p_changeset) : + NULL; + char *user = + p_user ? clean_xml (p_user) : NULL; first = 0; #if defined(_WIN32) || defined(__MINGW32__) /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */ fprintf (out, "\t\n"); else fprintf (out, ">\n"); } @@ -419,12 +431,16 @@ sqlite3_column_int64 (query, 6); if (first) { /* first WAY row */ - char *timestamp = clean_xml (p_timestamp); - char *changeset = clean_xml (p_changeset); + char *timestamp = + p_timestamp ? clean_xml (p_timestamp) : + NULL; + char *changeset = + p_changeset ? clean_xml (p_changeset) : + NULL; char *user = NULL; if (p_user) user = clean_xml (p_user); first = 0; #if defined(_WIN32) || defined(__MINGW32__) @@ -431,24 +447,31 @@ /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */ fprintf (out, "\t\n", - version, changeset, uid, - timestamp); - else - fprintf (out, - " version=\"%d\" changeset=\"%s\" user=\"%s\" uid=\"%d\" timestamp=\"%s\">\n", - version, changeset, user, uid, - timestamp); - free (changeset); if (user) - free (user); - free (timestamp); + { + fprintf (out, " user=\"%s\"", user); + free (user); + } + if (changeset) + { + fprintf (out, " changeset=\"%s\"", + changeset); + free (changeset); + } + if (timestamp) + { + fprintf (out, " timestamp=\"%s\"", + timestamp); + free (timestamp); + } + if (!version) + version = 1; + fprintf (out, " version=\"%d\"", version); + fprintf (out, " uid=\"%d\" >\n", uid); } /* NODE REF tag */ #if defined(_WIN32) || defined(__MINGW32__) /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */ fprintf (out, "\t\t\n", node_id); @@ -659,13 +682,17 @@ sqlite3_int64 way_id = sqlite3_column_int64 (query_way, 7); if (first) { - /* first WAY row */ - char *timestamp = clean_xml (p_timestamp); - char *changeset = clean_xml (p_changeset); + /* first RELATION row */ + char *timestamp = + p_timestamp ? clean_xml (p_timestamp) : + NULL; + char *changeset = + p_changeset ? clean_xml (p_changeset) : + NULL; char *user = NULL; if (p_user) user = clean_xml (p_user); first = 0; #if defined(_WIN32) || defined(__MINGW32__) @@ -672,23 +699,31 @@ /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */ fprintf (out, "\t\n", - version, changeset, uid, - timestamp); - else - fprintf (out, - " version=\"%d\" changeset=\"%s\" user=\"%s\" uid=\"%d\" timestamp=\"%s\">\n", - version, changeset, user, uid, - timestamp); - free (changeset); - free (user); - free (timestamp); + if (user) + { + fprintf (out, " user=\"%s\"", user); + free (user); + } + if (changeset) + { + fprintf (out, " changeset=\"%s\"", + changeset); + free (changeset); + } + if (timestamp) + { + fprintf (out, " timestamp=\"%s\"", + timestamp); + free (timestamp); + } + if (!version) + version = 1; + fprintf (out, " version=\"%d\"", version); + fprintf (out, " uid=\"%d\" >\n", uid); } /* NODE REF tag */ #if defined(_WIN32) || defined(__MINGW32__) /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */ fprintf (out, @@ -1560,10 +1595,23 @@ sqlite3_close (db_handle); fprintf (stderr, "DB '%s'\n", path); fprintf (stderr, "doesn't seems to contain valid OSM-RAW data ...\n\n"); return; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_osm_filter: %s\n", VERSION); + fprintf (stderr, "target CPU ..........: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite .......: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ..........: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -1570,10 +1618,11 @@ fprintf (stderr, "\n\nusage: spatialite_osm_filter ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-o or --osm-path pathname the OSM-XML [output] file path\n"); fprintf (stderr, "-w or --wkt-mask-path pathname path of text file [WKT mask]\n"); fprintf (stderr, @@ -1634,10 +1683,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-o") == 0) { next_arg = ARG_OSM_PATH; continue; Index: spatialite_osm_map.c ================================================================== --- spatialite_osm_map.c +++ spatialite_osm_map.c @@ -365,15 +365,14 @@ sqlite3_bind_blob (layer->ins_point_stmt, 4, blob, blob_size, free); ret = sqlite3_step (layer->ins_point_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_POINT %s\n", - layer_name); - sqlite3_finalize (layer->ins_point_stmt); - layer->ins_point_stmt = NULL; - return 0; + fprintf (stderr, + "sqlite3_step() error: INS_POINT %s (%s)\n", + layer_name, sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } } return 1; @@ -404,14 +403,13 @@ sqlite3_bind_blob (params->ins_generic_point_stmt, 3, blob, blob_size, free); ret = sqlite3_step (params->ins_generic_point_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POINT\n"); - sqlite3_finalize (params->ins_generic_point_stmt); - params->ins_generic_point_stmt = NULL; - return 0; + fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POINT (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } static int @@ -466,14 +464,13 @@ sqlite3_bind_blob (params->ins_addresses_stmt, 8, blob, blob_size, free); ret = sqlite3_step (params->ins_addresses_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_ADDRESSES\n"); - sqlite3_finalize (params->ins_addresses_stmt); - params->ins_addresses_stmt = NULL; - return 0; + fprintf (stderr, "sqlite3_step() error: INS_ADDRESSES (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } static int @@ -488,14 +485,13 @@ sqlite3_bind_double (params->ins_tmp_nodes_stmt, 2, node->latitude); sqlite3_bind_double (params->ins_tmp_nodes_stmt, 3, node->longitude); ret = sqlite3_step (params->ins_tmp_nodes_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_TMP_NODES\n"); - sqlite3_finalize (params->ins_tmp_nodes_stmt); - params->ins_tmp_nodes_stmt = NULL; - return 0; + fprintf (stderr, "sqlite3_step() error: INS_TMP_NODES (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } static int consume_node (const void *user_data, const readosm_node * node) { @@ -806,15 +802,13 @@ blob_size, SQLITE_STATIC); ret = sqlite3_step (layer->ins_linestring_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; fprintf (stderr, - "sqlite3_step() error: INS_LINESTRING %s\n", - layer_name); - sqlite3_finalize (layer->ins_linestring_stmt); - layer->ins_linestring_stmt = NULL; - return 0; + "sqlite3_step() error: INS_LINESTRING %s (%s)\n", + layer_name, sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } } return 1; @@ -860,15 +854,13 @@ blob_size, SQLITE_STATIC); ret = sqlite3_step (layer->ins_polygon_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; fprintf (stderr, - "sqlite3_step() error: INS_POLYGON %s\n", - layer_name); - sqlite3_finalize (layer->ins_polygon_stmt); - layer->ins_polygon_stmt = NULL; - return 0; + "sqlite3_step() error: INS_POLYGON %s (%s)\n", + layer_name, sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } } return 1; @@ -892,14 +884,14 @@ sqlite3_bind_blob (params->ins_generic_linestring_stmt, 3, blob, blob_size, SQLITE_STATIC); ret = sqlite3_step (params->ins_generic_linestring_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_GENERIC_LINESTRING\n"); - sqlite3_finalize (params->ins_generic_linestring_stmt); - params->ins_generic_linestring_stmt = NULL; - return 0; + fprintf (stderr, + "sqlite3_step() error: INS_GENERIC_LINESTRING (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } static int @@ -920,14 +912,13 @@ sqlite3_bind_blob (params->ins_generic_polygon_stmt, 3, blob, blob_size, SQLITE_STATIC); ret = sqlite3_step (params->ins_generic_polygon_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POLYGON\n"); - sqlite3_finalize (params->ins_generic_polygon_stmt); - params->ins_generic_polygon_stmt = NULL; - return 0; + fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POLYGON (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } static int @@ -945,14 +936,13 @@ SQLITE_STATIC); ret = sqlite3_step (params->ins_tmp_ways_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_TMP_WAYS\n"); - sqlite3_finalize (params->ins_tmp_ways_stmt); - params->ins_tmp_ways_stmt = NULL; - return 0; + fprintf (stderr, "sqlite3_step() error: INS_TMP_WAYS (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } static int eval_way (struct aux_params *params, const readosm_way * way, int area, unsigned char *blob, int blob_size) @@ -1420,15 +1410,13 @@ blob_size, free); ret = sqlite3_step (layer->ins_linestring_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; fprintf (stderr, - "sqlite3_step() error: INS_MULTILINESTRING %s\n", - layer_name); - sqlite3_finalize (layer->ins_linestring_stmt); - layer->ins_linestring_stmt = NULL; - return 0; + "sqlite3_step() error: INS_MULTILINESTRING %s (%s)\n", + layer_name, sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } } return 1; @@ -1819,15 +1807,13 @@ blob_size, free); ret = sqlite3_step (layer->ins_polygon_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; fprintf (stderr, - "sqlite3_step() error: INS_MULTIPOLYGON %s\n", - layer_name); - sqlite3_finalize (layer->ins_polygon_stmt); - layer->ins_polygon_stmt = NULL; - return 0; + "sqlite3_step() error: INS_MULTIPOLYGON %s (%s)\n", + layer_name, sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } } return 1; @@ -1862,14 +1848,13 @@ blob_size, free); ret = sqlite3_step (params->ins_generic_linestring_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; fprintf (stderr, - "sqlite3_step() error: INS_GENERIC_MULTILINESTRING\n"); - sqlite3_finalize (params->ins_generic_linestring_stmt); - params->ins_generic_linestring_stmt = NULL; - return 0; + "sqlite3_step() error: INS_GENERIC_MULTILINESTRING (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } static int @@ -1901,14 +1886,14 @@ sqlite3_bind_blob (params->ins_generic_polygon_stmt, 3, blob, blob_size, free); ret = sqlite3_step (params->ins_generic_polygon_stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) return 1; - fprintf (stderr, "sqlite3_step() error: INS_GENERIC_MULTIPOLYGON\n"); - sqlite3_finalize (params->ins_generic_polygon_stmt); - params->ins_generic_polygon_stmt = NULL; - return 0; + fprintf (stderr, + "sqlite3_step() error: INS_GENERIC_MULTIPOLYGON (%s)\n", + sqlite3_errmsg (params->db_handle)); + return 1; } return 1; } static int @@ -2022,15 +2007,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -2542,10 +2527,26 @@ do_spatial_index (db_handle, table, geom); } } sqlite3_free_table (results); } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_osm_map: %s\n", VERSION); + fprintf (stderr, "target CPU .......: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite ....: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 .......: %s\n", sqlite3_libversion ()); + fprintf (stderr, "libreadosm .......: %s\n", readosm_version ()); + fprintf (stderr, "libexpat .........: %s\n", readosm_expat_version ()); + fprintf (stderr, "zlib .............: %s\n", readosm_zlib_version ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -2552,10 +2553,11 @@ fprintf (stderr, "\n\nusage: spatialite_osm_map ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-o or --osm-path pathname the OSM-XML file path\n"); fprintf (stderr, " both OSM-XML (*.osm) and OSM-ProtoBuf\n"); fprintf (stderr, " (*.osm.pbf) are indifferently supported.\n\n"); @@ -2623,10 +2625,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-o") == 0) { next_arg = ARG_OSM_PATH; continue; Index: spatialite_osm_net.c ================================================================== --- spatialite_osm_net.c +++ spatialite_osm_net.c @@ -1502,15 +1502,15 @@ } sqlite3_free_table (results); if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -2239,10 +2239,26 @@ } fclose (out); return 1; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_osm_net: %s\n", VERSION); + fprintf (stderr, "target CPU .......: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite ....: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 .......: %s\n", sqlite3_libversion ()); + fprintf (stderr, "libreadosm .......: %s\n", readosm_version ()); + fprintf (stderr, "libexpat .........: %s\n", readosm_expat_version ()); + fprintf (stderr, "zlib .............: %s\n", readosm_zlib_version ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -2249,10 +2265,11 @@ fprintf (stderr, "\n\nusage: spatialite_osm_net ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-o or --osm-path pathname the OSM-XML file path\n"); fprintf (stderr, " both OSM-XML (*.osm) and OSM-ProtoBuf\n"); fprintf (stderr, " (*.osm.pbf) are indifferently supported.\n\n"); @@ -2347,10 +2364,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-o") == 0) { next_arg = ARG_OSM_PATH; continue; Index: spatialite_osm_overpass.c ================================================================== --- spatialite_osm_overpass.c +++ spatialite_osm_overpass.c @@ -27,10 +27,18 @@ #include #include #include #include +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else +#include "config.h" +#endif + +#ifdef ENABLE_LIBXML2 /* only if LIBXML2 is enabled */ + #include #include #include #include @@ -1197,15 +1205,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -3995,10 +4003,24 @@ *maxy = save; ret = 0; } return ret; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_osm_overpass: %s\n", VERSION); + fprintf (stderr, "target CPU ............: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite .........: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ............: %s\n", sqlite3_libversion ()); + fprintf (stderr, "libxml2 ...............: %s\n", LIBXML_DOTTED_VERSION); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -4005,10 +4027,11 @@ fprintf (stderr, "\n\nusage: spatialite_osm_overpass ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite DB path\n"); fprintf (stderr, "-minx or --bbox-minx coord BoundingBox - west longitude\n"); fprintf (stderr, @@ -4036,14 +4059,23 @@ "-jo or --journal-off unsafe [but faster] mode\n"); fprintf (stderr, "-p or --preserve skipping final cleanup (preserving OSM tables)\n"); } +#endif /* end LIBXML2 conditional */ + int main (int argc, char *argv[]) { /* the MAIN function simply perform arguments checking */ + +#ifndef ENABLE_LIBXML2 /* only if LIBXML2 is disabled */ + fprintf (stderr, "\nthis copy of \"spatialite_osm_overpass\"\n" + "was built by disabling LIBXML2 support.\n" + "Sorry, cowardly quitting ...\n"); + return 0; +#else sqlite3 *handle; int i; int next_arg = ARG_NONE; const char *osm_url = "http://overpass-api.de/api"; const char *db_path = NULL; @@ -4150,10 +4182,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-d") == 0) { next_arg = ARG_DB_PATH; continue; @@ -4586,6 +4624,7 @@ sqlite3_close (handle); spatialite_cleanup_ex (cache); spatialite_shutdown (); downloader_cleanup (&downloader); return 0; +#endif /* end LIBXML2 conditional */ } Index: spatialite_osm_raw.c ================================================================== --- spatialite_osm_raw.c +++ spatialite_osm_raw.c @@ -618,15 +618,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -931,10 +931,26 @@ fprintf (stderr, "DB '%s'\n", path); fprintf (stderr, "doesn't seems to contain valid Spatial Metadata ...\n\n"); fprintf (stderr, "Please, initialize Spatial Metadata\n\n"); return; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_osm_raw: %s\n", VERSION); + fprintf (stderr, "target CPU .......: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite ....: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 .......: %s\n", sqlite3_libversion ()); + fprintf (stderr, "libreadosm .......: %s\n", readosm_version ()); + fprintf (stderr, "libexpat .........: %s\n", readosm_expat_version ()); + fprintf (stderr, "zlib .............: %s\n", readosm_zlib_version ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -941,10 +957,11 @@ fprintf (stderr, "\n\nusage: spatialite_osm_raw ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-o or --osm-path pathname the OSM-file path\n"); fprintf (stderr, " both OSM-XML (*.osm) and OSM-ProtoBuf\n"); fprintf (stderr, " (*.osm.pbf) are indifferently supported.\n\n"); @@ -1018,10 +1035,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-o") == 0) { next_arg = ARG_OSM_PATH; continue; Index: spatialite_tool.c ================================================================== --- spatialite_tool.c +++ spatialite_tool.c @@ -95,15 +95,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -226,10 +226,23 @@ if (ret != SQLITE_OK) fprintf (stderr, "sqlite3_close() error: %s\n", sqlite3_errmsg (handle)); spatialite_cleanup_ex (cache); } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "exif_loader .: %s\n", VERSION); + fprintf (stderr, "target CPU ..: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ..: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -238,10 +251,11 @@ "==============================================================\n"); fprintf (stderr, "CMD has to be one of the followings:\n"); fprintf (stderr, "------------------------------------\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-i or --import import [CSV/TXT, DBF or SHP]\n"); fprintf (stderr, "-e or --export-shp exporting some shapefile\n"); fprintf (stderr, "\nsupported ARGs are:\n"); @@ -334,10 +348,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcasecmp (argv[i], "--shapefile") == 0) { next_arg = ARG_SHP; in_shp = 1; ADDED spatialite_xml2utf8.c Index: spatialite_xml2utf8.c ================================================================== --- spatialite_xml2utf8.c +++ spatialite_xml2utf8.c @@ -0,0 +1,126 @@ +/* +/ spatialite_xml2utf8 +/ +/ a tool converting the charset encoding for any XML as UTF-8 +/ +/ version 1.0, 2017 August 25 +/ +/ Author: Sandro Furieri a.furieri@lqt.it +/ +/ Copyright (C) 2017 Alessandro Furieri +/ +/ This program is free software: you can redistribute it and/or modify +/ it under the terms of the GNU General Public License as published by +/ the Free Software Foundation, either version 3 of the License, or +/ (at your option) any later version. +/ +/ This program is distributed in the hope that it will be useful, +/ but WITHOUT ANY WARRANTY; without even the implied warranty of +/ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/ GNU General Public License for more details. +/ +/ You should have received a copy of the GNU General Public License +/ along with this program. If not, see . +/ +*/ + +#include +#include + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else +#include "config.h" +#endif + +#if defined(__MINGW32__) || defined(_WIN32) +#define LIBICONV_STATIC +#include +#define LIBCHARSET_STATIC +#ifdef _MSC_VER +/* isn't supported on OSGeo4W */ +/* applying a tricky workaround to fix this issue */ +extern const char *locale_charset (void); +#else /* sane Windows - not OSGeo4W */ +#include +#endif /* end localcharset */ +#else /* not MINGW32 - WIN32 */ +#if defined(__APPLE__) || defined(__ANDROID__) +#include +#include +#else /* neither Mac OsX nor Android */ +#include +#include +#endif +#endif + +static void +do_convert (iconv_t cvt, char *in, char *out, size_t i_len) +{ + size_t i; + size_t max_len = i_len * 4; + size_t o_len = max_len; + char *p_in = in; + char *p_out = out; + if (iconv (cvt, &p_in, &i_len, &p_out, &o_len) == (size_t) (-1)) + { + fprintf (stderr, "invalid character sequence !!!\n"); + return; + } + for (i = 0; i < max_len - o_len; i++) + putchar (out[i]); + putchar ('\n'); +} + +int +main (int argc, const char *argv[]) +{ + int lineno = 0; + size_t count; + char *out = malloc (1024 * 1024); + char *in = malloc (1024 * 1924); + char *p_in; + iconv_t cvt; + const char *charset = NULL; + if (argc != 2) + { + fprintf (stderr, + "usage: spatialite_utf8 input-charset output\n"); + return -1; + } + charset = argv[1]; + + cvt = iconv_open ("UTF-8", charset); + if (cvt == (iconv_t) (-1)) + { + fprintf (stderr, "Unknown charset: %s\n", charset); + goto stop; + } + + count = 0; + p_in = in; + while (1) + { + int c = getchar (); + if (c == EOF || c == '\n') + { + if (lineno > 0) + do_convert (cvt, in, out, count); + else + printf ("\n"); + if (c == EOF) + break; + lineno++; + count = 0; + p_in = in; + continue; + } + *p_in++ = c; + count++; + } + + iconv_close (cvt); + + stop: + return 0; +} Index: spatialite_xml_collapse.c ================================================================== --- spatialite_xml_collapse.c +++ spatialite_xml_collapse.c @@ -43,10 +43,16 @@ #include #include #include #include + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else +#include "config.h" +#endif #define ARG_NONE 0 #define ARG_DB_PATH 1 #define ARG_CACHE_SIZE 2 #define ARG_NAME_LEVEL 3 @@ -1863,15 +1869,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } @@ -2034,10 +2040,23 @@ /* enabling PK/FK constraints */ sqlite3_exec (db_handle, "PRAGMA foreign_keys = 1", NULL, NULL, NULL); *handle = db_handle; return; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_osm_overpass: %s\n", VERSION); + fprintf (stderr, "target CPU ............: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite .........: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 ............: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -2044,10 +2063,11 @@ fprintf (stderr, "\n\nusage: spatialite_xml_collapse ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite DB path\n\n"); fprintf (stderr, "you can specify the following options as well\n"); fprintf (stderr, "-dd or --delete-duplicates remove all duplicate rows except one\n"); @@ -2109,10 +2129,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-d") == 0) { next_arg = ARG_DB_PATH; continue; Index: spatialite_xml_load.c ================================================================== --- spatialite_xml_load.c +++ spatialite_xml_load.c @@ -45,11 +45,15 @@ #include #include #include +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else #include "config.h" +#endif #ifdef SPATIALITE_AMALGAMATION #include #else #include @@ -2211,15 +2215,15 @@ if (count > 0) return; /* all right, it's empty: proceding to initialize */ - strcpy (sql, "SELECT InitSpatialMetadata(1)"); + strcpy (sql, "SELECT InitSpatialMetadataFull(1)"); ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { - fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg); + fprintf (stderr, "InitSpatialMetadataFull() error: %s\n", err_msg); sqlite3_free (err_msg); return; } } Index: spatialite_xml_print.c ================================================================== --- spatialite_xml_print.c +++ spatialite_xml_print.c @@ -42,11 +42,15 @@ #include #include #include +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else #include "config.h" +#endif #ifdef SPATIALITE_AMALGAMATION #include #else #include @@ -920,10 +924,23 @@ /* enabling PK/FK constraints */ sqlite3_exec (db_handle, "PRAGMA foreign_keys = 1", NULL, NULL, NULL); *handle = db_handle; return; } + +static void +do_version () +{ +/* printing version infos */ + fprintf( stderr, "\nVersion infos\n"); + fprintf( stderr, "===========================================\n"); + fprintf (stderr, "spatialite_xml_print: %s\n", VERSION); + fprintf (stderr, "target CPU .........: %s\n", spatialite_target_cpu ()); + fprintf (stderr, "libspatialite ......: %s\n", spatialite_version ()); + fprintf (stderr, "libsqlite3 .........: %s\n", sqlite3_libversion ()); + fprintf (stderr, "\n"); +} static void do_help () { /* printing the argument list */ @@ -930,10 +947,11 @@ fprintf (stderr, "\n\nusage: spatialite_xml_printf ARGLIST\n"); fprintf (stderr, "==============================================================\n"); fprintf (stderr, "-h or --help print this help message\n"); + fprintf (stderr, "-v or --version print version infos\n"); fprintf (stderr, "-d or --db-path pathname the SpatiaLite DB [INPUT] path\n\n"); fprintf (stderr, "-x or --xml-path pathname the XML file [OUTPUT] path\n"); fprintf (stderr, @@ -980,10 +998,16 @@ if (strcasecmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) { do_help (); return -1; + } + if (strcasecmp (argv[i], "--version") == 0 + || strcmp (argv[i], "-v") == 0) + { + do_version (); + return -1; } if (strcmp (argv[i], "-x") == 0) { next_arg = ARG_XML_PATH; continue; Index: spatialite_xml_validator.c ================================================================== --- spatialite_xml_validator.c +++ spatialite_xml_validator.c @@ -26,11 +26,17 @@ #include #include #include +#if defined(_WIN32) && !defined(__MINGW32__) +#include "config-msvc.h" +#else #include "config.h" +#endif + +#ifdef ENABLE_LIBXML2 /* only if LIBXML2 is enabled */ #include #include #include #include @@ -634,14 +640,23 @@ free (schemaURI); fprintf (stderr, "ERROR - invalid XML: %s\n\n", path); return 0; } +#endif /* end LIBXML2 conditional */ + int main (int argc, char *argv[]) { /* the MAIN function mainly perform arguments checking */ + +#ifndef ENABLE_LIBXML2 /* only if LIBXML2 is disabled */ + fprintf (stderr, "\nthis copy of \"spatialite_xml_validator\"\n" + "was built by disabling LIBXML2 support.\n" + "Sorry, cowardly quitting ...\n"); + return 0; +#else const char *xml_path = NULL; const char *list_path = NULL; int single = 0; int list = 0; int err = 1; @@ -713,6 +728,7 @@ return 0; error: cache_cleanup (&cache); xmlCleanupParser (); return -1; +#endif /* end LIBXML2 conditional */ }