[SCM] shapelib branch, master, updated. debian/1.2.10-7-1-g1207cdd

Arto Jantunen viiru at debian.org
Sat Nov 9 12:39:47 UTC 2013


The following commit has been merged in the master branch:
commit 1207cdd579102cfa9d9bab78144b22ff454f1f29
Author: Arto Jantunen <viiru at debian.org>
Date:   Fri May 18 10:33:11 2012 +0300

    Imported Upstream version 1.3.0 (Closes: #526984)

diff --git a/.cvsignore b/.cvsignore
index fead322..6fbd556 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,10 +1,15 @@
-shpcreate
-shpadd
-shpdump
-dbfcreate
 dbfadd
+dbfcreate
 dbfdump
-shptest
-shptreedump
-shputils
+shpadd
+shpcreate
+shpdump
 shprewind
+shptreedump
+shptest
+*.dll
+*.lib
+*.exp
+*.la
+*.lo
+.libs
diff --git a/ChangeLog b/ChangeLog
index 0675b70..d0227a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,249 @@
+2012-01-27  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shptree.c: optimize quadtree generation (gdal #4472)
+
+2012-01-24  Frank Warmerdam  <warmerdam at google.com>
+
+	* shpopen.c: fix memory leaks on failure to open .shp file.
+
+2011-12-11  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shptree.c,h: Use SAHooks for .qix access (gdal #3365)
+
+2011-09-14  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: fix missing cast (#2344)
+
+2011-07-24    <warmerdam at pobox.com>
+
+	* shpopen.c, dbfopen.c, shptree.c, shapefil.h: Minimize use of 
+	CPL services in favor of SAHooks.Error(). 
+
+	* Makefile: Remove all the shared library building stuff, it is just
+	too half assed, and results in all sorts of bug reports and complaints.
+	Instead just install a static libshp.a.
+
+2011-07-23    <warmerdam at pobox.com>
+
+	* Makefile: build shpdumptree as part of all target (#1648).
+
+	* shpopen.c: fix memory leaks in error cases (#2061)
+
+	* contrib/*.c: Include stdlib.h and strings.h (#2146)
+
+	* shpdump.c: change to use %.15g for coordinate reporting. (#2277)
+
+2011-05-13  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c, shapelib.h: Add functions to reorder and alter
+	field definitions.  DBFReorderFields() and DBFAlterFields().
+
+2011-05-07  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Ensure pending record is flushed when adding a native
+	field (gdal #4073).
+
+2011-04-16  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shapefil.h: avoid warnings with SHP_CVSID on gcc.
+
+2010-12-06  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: fix read past end of init data fetching code page 
+	http://bugzilla.maptools.org/show_bug.cgi?id=2276
+
+2010-07-01  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: do not error out on a shape with zero vertices.
+
+	* shpdump.c: do not crash if null shape returned by read object.
+
+2010-06-29  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shptree.c: fix sign of Z and M comparisons in SHPCheckObjectContained.
+	(http://bugzilla.maptools.org/show_bug.cgi?id=2223)
+
+2010-01-28  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c/shapefil.h: Handle the .shp file length limits more
+	gracefully. (http://trac.osgeo.org/gdal/ticket/3236)
+
+	* shpopen.c: Improve the numerical accurancy of algorithms in
+	SHPRewind() (http://trac.osgeo.org/gdal/ticket/3363).
+
+2010-01-16  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: support passing in zero/nulls to create an empty
+	SHPObject: http://bugzilla.maptools.org/show_bug.cgi?id=2148
+
+2009-10-29  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: avoid crash risk for truncated files.
+	http://trac.osgeo.org/gdal/ticket/3093
+
+2009-09-17  Bram de Greve <bram.degreve at bramz.net>
+
+	* shpopen.c: on Win32, define snprintf as alias to _snprintf
+
+2008-11-12  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shptree.c: improve safety in face of buggy .shp file.
+	http://trac.osgeo.org/gdal/ticket/2610
+
+	* dbfopen.c: DBFCreateField() can now also operate on files with
+	records, c/o Martin Dobias.
+	https://trac.osgeo.org/gdal/ticket/2672
+
+2008-11-11  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Introduce DBFDeleteField() function from Martin Dobias.
+	http://trac.osgeo.org/gdal/ticket/2671
+
+2008-03-14  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* Correct crash on buggy geometries (Even Rouault).
+	http://trac.osgeo.org/gdal/ticket/2218
+
+2008-01-16  Bram de Greve <bram.degreve at bramz.net>
+
+	* shapefil.h, safileio.c:  add file hooks that accept UTF-8
+	encoded filenames on some platforms.  Use SASetupUtf8Hooks
+	to setup the hooks and check SHPAPI_UTF8_HOOKS for its
+	availability.  Currently, this is only available on the Windows
+	platform that decodes the UTF-8 filenames to wide character
+	strings and feed them to _wfopen and _wremove.
+
+2008-01-10  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shapefil.h: Avoid _ prefix on #defines.
+	http://bugzilla.maptools.org/show_bug.cgi?id=1840
+
+2008-01-03  Bram de Greve <bram.degreve at bramz.net>
+
+	* dbfopen.c: in DBFCreate, use default code page
+	LDID/87 (= 0x57, ANSI) instead of LDID/3.  This seems
+	to be the same as what ESRI would be doing by default.
+
+2007-12-30  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpadd.c/shpcreate.c: Add support for z and m files.
+
+	* Massive overhaul to use hooks for file io, etc.
+
+2007-12-18  Bram de Greve <bram.degreve at bramz.net>
+
+	* dbfopen.c/shapefil.h/safileio.c:  create hook for client
+	specific atof http://bugzilla.maptools.org/show_bug.cgi?id=1615
+
+	* dbfopen.c: check for NULL handle before closing cpCPG file,
+	and close after reading.
+
+2007-12-15  Bram de Greve <bram.degreve at bramz.net>
+
+	* dbfopen.c/shapefil.h/safileio.c: read the Code Page information 
+	from the DBF file, and exports this information as a string through 
+	the DBFGetCodePage function.  This is either the number from the LDID
+	header field ("LDID/<number>") or as the content of an accompanying 
+	.CPG file.	When creating a DBF file, the code can be set using 
+	DBFCreateEx.
+
+2007-12-12  Bram de Greve <bram.degreve at bramz.net>
+
+	* dbfopen.c: check for NULL handle in DBFClose.
+
+2007-11-21  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c/shapefil.h: Don't keep .shx file open in read-only mode.
+	http://trac.osgeo.org/gdal/ticket/1956
+
+2007-11-14  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: checks after mallocs to detect for corrupted/voluntary 
+	broken shapefiles.  http://trac.osgeo.org/gdal/ticket/1991
+
+2007-09-03  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpgeo.c: Fixed SHPDimension() (missing breaks) in shpgeo.c.
+	Fix contributed by Andrea Peri.
+
+	* dbfopen.c: Move the static dDoubleField return buffer into DBFInfo
+	structure to avoid multithreaded risks. 
+
+	* dbfopen.c: Simplify DBFReadTuple() to avoid use of static tuple.
+	Note that this means DBFReadTuple() results are only valid till the 
+	next record is read for any reason.
+
+2007-06-21  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: Fix for SHPRewind() for "contact at one vertex" 
+	cases in rings. http://trac.osgeo.org/gdal/ticket/976
+
+2006-11-06  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* contrib/shpgeo.c: Modified SHPProject to use pj_transform() so 
+	it works for datums and stuff.  Submitted by Steffen Macke.
+
+2006-09-04  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpeopen.c: (MLoskot) Added stronger test of Shapefile reading 
+	failures, e.g. truncated files.  The problem was discovered by Tim 
+	Sutton and reported here:
+	      https://svn.qgis.org/trac/ticket/200
+
+2006-06-17  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: use calloc() for DBFInfo in DBFCreate() to ensure
+	all fields initialized to zero if not otherwise mentioned.
+
+	* dbfopen.c: Don't allow creation of string fields with width larger
+	than 255 per http://bugzilla.maptools.org/show_bug.cgi?id=1434
+
+2006-06-16  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Don't treat decimals value as high order field length
+	for strings, as it causes serious bugs in some cases such as
+	http://bugzilla.remotesensing.org/show_bug.cgi?id=1202
+
+	* dbfopen.c: Made static field buffer in DBFReadAttribute() into a
+	field in the DBFInfo structure to avoid multi-threading problems.
+
+2006-03-29  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Fixed bug in DBFCloneEmpty() (treating pachFieldType as
+	an array of int).
+
+2006-02-08  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Changed to put spaces into string fields that are NULL
+	as per http://bugzilla.maptools.org/show_bug.cgi?id=316.
+
+2006-01-26  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c, shapefil.h, shpdump.c: Added bMeasureIsUsed support as
+	per http://bugzilla.maptools.org/show_bug.cgi?id=1249
+	
+2006-01-04  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c/shapefil.h: Added functions to check if dbf record is
+	deleted, and to mark it as deleted.
+
+2005-02-11  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: Check panPartStart[0] is 0 in SHPCreateObject().
+
+	* Fixed bug 305 in DBFCloneEmpty() - header length problem.
+
+	* Make the pszStringField buffer for DBFReadAttribute() static char 
+	[256] as per bug 306.
+
+2004-09-15  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: treat all blanks as NULL in DBFIsAttributeNULL().
+
+2004-06-23  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* contrib/shpsort.c: added new contribute program from Eric Miller.
+
 2003-04-07  Frank Warmerdam  <warmerdam at pobox.com>
 
 	* Issue 1.2.10 Release.
diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE
new file mode 100644
index 0000000..b86f349
--- /dev/null
+++ b/HOWTO-RELEASE
@@ -0,0 +1,16 @@
+	Producing Shapelib Releases
+	===========================
+
+1) Update web/release.html with change notes on the new release and commit.
+
+2) Build the release files. 
+
+   ./mkrelease.sh 1.3.0
+
+3) Upload:
+
+   scp shapelib-1.3.0{.tar.gz,.zip} warmerdam at upload.osgeo.org:/osgeo/download/shapelib 
+   ... add upload notes to maptools.org ...
+
+4) Announce on shapelib mailing list. 
+
diff --git a/Makefile b/Makefile
index 6d24091..0c41d8a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,16 @@
 
-#LINKOPT	=	/usr/local/lib/libdbmalloc.a
-CFLAGS	=	-g
+PREFIX	=	/usr/local
+CFLAGS	=	-g -Wall -fPIC
+#CFLAGS  =       -g -DUSE_CPL
+#CC = g++
+
+LIBOBJ	=	shpopen.o dbfopen.o safileio.o shptree.o 
+SHPBIN	=	shpcreate shpadd shpdump shprewind dbfcreate dbfadd dbfdump \
+		shptreedump 
 
 default:	all
 
-all:	shpcreate shpadd shpdump shprewind dbfcreate dbfadd dbfdump shptest
+all:	$(SHPBIN) shptest lib
 
 shpopen.o:	shpopen.c shapefil.h
 	$(CC) $(CFLAGS) -c shpopen.c
@@ -15,42 +21,42 @@ shptree.o:	shptree.c shapefil.h
 dbfopen.o:	dbfopen.c shapefil.h
 	$(CC) $(CFLAGS) -c dbfopen.c
 
-shpcreate:	shpcreate.c shpopen.o
-	$(CC) $(CFLAGS) shpcreate.c shpopen.o $(LINKOPT) -o shpcreate
+safileio.o:	safileio.c shapefil.h
+	$(CC) $(CFLAGS) -c safileio.c
+
+shpcreate:	shpcreate.c shpopen.o safileio.o 
+	$(CC) $(CFLAGS) shpcreate.c shpopen.o safileio.o $(LINKOPT) -o shpcreate
 
-shpadd:		shpadd.c shpopen.o
-	$(CC) $(CFLAGS) shpadd.c shpopen.o $(LINKOPT) -o shpadd
+shpadd:		shpadd.c shpopen.o safileio.o
+	$(CC) $(CFLAGS) shpadd.c shpopen.o safileio.o $(LINKOPT) -o shpadd
 
-shpdump:	shpdump.c shpopen.o
-	$(CC) $(CFLAGS) shpdump.c shpopen.o $(LINKOPT) -o shpdump
+shpdump:	shpdump.c shpopen.o safileio.o
+	$(CC) $(CFLAGS) shpdump.c shpopen.o safileio.o $(LINKOPT) -o shpdump
 
-shprewind:	shprewind.c shpopen.o
-	$(CC) $(CFLAGS) shprewind.c shpopen.o $(LINKOPT) -o shprewind
+shprewind:	shprewind.c shpopen.o safileio.o
+	$(CC) $(CFLAGS) shprewind.c shpopen.o safileio.o $(LINKOPT) -o shprewind
 
-dbfcreate:	dbfcreate.c dbfopen.o
-	$(CC) $(CFLAGS) dbfcreate.c dbfopen.o $(LINKOPT) -o dbfcreate
+dbfcreate:	dbfcreate.c dbfopen.o safileio.o
+	$(CC) $(CFLAGS) dbfcreate.c dbfopen.o safileio.o $(LINKOPT) -o dbfcreate
 
-dbfadd:		dbfadd.c dbfopen.o
-	$(CC) $(CFLAGS) dbfadd.c dbfopen.o $(LINKOPT) -o dbfadd
+dbfadd:		dbfadd.c dbfopen.o safileio.o
+	$(CC) $(CFLAGS) dbfadd.c dbfopen.o safileio.o $(LINKOPT) -o dbfadd
 
-dbfdump:	dbfdump.c dbfopen.o
-	$(CC) $(CFLAGS) dbfdump.c dbfopen.o $(LINKOPT) -o dbfdump
+dbfdump:	dbfdump.c dbfopen.o safileio.o
+	$(CC) $(CFLAGS) dbfdump.c dbfopen.o safileio.o $(LINKOPT) -o dbfdump
 
-shptest:	shptest.c shpopen.o
-	$(CC) $(CFLAGS) shptest.c shpopen.o $(LINKOPT) -o shptest
+shptest:	shptest.c shpopen.o safileio.o
+	$(CC) $(CFLAGS) shptest.c shpopen.o safileio.o $(LINKOPT) -o shptest
 
-shputils:	shputils.c shpopen.o dbfopen.o
-	$(CC) $(CFLAGS) shputils.c shpopen.o dbfopen.o $(LINKOPT) -o shputils
+shputils:	shputils.c shpopen.o safileio.o dbfopen.o 
+	$(CC) $(CFLAGS) shputils.c shpopen.o safileio.o dbfopen.o  $(LINKOPT) -o shputils
 
-shptreedump:	shptreedump.c shptree.o shpopen.o
-	$(CC) $(CFLAGS) shptreedump.c shptree.o shpopen.o $(LINKOPT) \
+shptreedump:	shptreedump.c shptree.o shpopen.o safileio.o
+	$(CC) $(CFLAGS) shptreedump.c shptree.o shpopen.o safileio.o $(LINKOPT) \
 		-o shptreedump
 
 clean:
-	rm -f *.o dbfdump dbfcreate dbfadd shpdump shpcreate shpadd shputils
-	rm -f shptreedump
-	rm -rf *.lo *.la .libs
-	rm -f shptest
+	rm -f *.o shptest $(SHPBIN) libshp.a 
 
 test:	test2 test3
 
@@ -91,52 +97,17 @@ test3:
 	fi
 
 
-# -----------------------------------------------------------------------------
-# The following is contributed by Jan-Oliver Wagner, and should allow for
-# creating shared libraries on most platforms with gcc, and libtool installed.
-
-SHPLIB_VERSION=1.2.9
-LIBSHP_VERSION=1.0.1 # still once to be changed manually (see for 1:1:0), sorry
-
-lib:
-	/bin/sh ./libtool --mode=compile gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1  -I. -I. -I/usr/local/include    -g -O2 -c shpopen.c
-	gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c  -fPIC -DPIC shpopen.c -o .libs/shpopen.lo
-	gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c shpopen.c -o shpopen.o >/dev/null 2>&1
-	mv -f .libs/shpopen.lo shpopen.lo
-	/bin/sh ./libtool --mode=compile gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1  -I. -I. -I/usr/local/include    -g -O2 -c shptree.c
-	rm -f .libs/shptree.lo
-	gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c  -fPIC -DPIC shptree.c -o .libs/shptree.lo
-	gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c shptree.c -o shptree.o >/dev/null 2>&1
-	mv -f .libs/shptree.lo shptree.lo
-	/bin/sh ./libtool --mode=compile gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1  -I. -I. -I/usr/local/include    -g -O2 -c dbfopen.c
-	rm -f .libs/dbfopen.lo
-	gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c  -fPIC -DPIC dbfopen.c -o .libs/dbfopen.lo
-	gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c dbfopen.c -o dbfopen.o >/dev/null 2>&1
-	mv -f .libs/dbfopen.lo dbfopen.lo
-	/bin/sh ./libtool --mode=link gcc  -g -O2  -o libshp.la -rpath /usr/local/lib -version-info 1:1:0 shpopen.lo shptree.lo dbfopen.lo  
-	rm -fr .libs/libshp.la .libs/libshp.* .libs/libshp.*
-	rm -fr .libs/libshp.lax
-	mkdir .libs/libshp.lax
-	/usr/bin/ld -G -h libshp.so.1 -o .libs/libshp.so.$(LIBSHP_VERSION)  shpopen.lo shptree.lo dbfopen.lo  -lc
-
-	(cd .libs && rm -f libshp.so.1 && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so.1)
-	(cd .libs && rm -f libshp.so && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so)
-	ar cru .libs/libshp.a  shpopen.o shptree.o dbfopen.o 
-	ranlib .libs/libshp.a
-	rm -fr .libs/libshp.lax
-	(cd .libs && rm -f libshp.la && ln -s ../libshp.la libshp.la)
-
-lib_install:
-	cp .libs/libshp.la .libs/libshp.lai
-	/bin/sh ./mkinstalldirs /usr/local/lib
-	/bin/sh ./libtool  --mode=install /usr/bin/install -c libshp.la /usr/local/lib/libshp.la
-	/usr/bin/install -c .libs/libshp.so.$(LIBSHP_VERSION) /usr/local/lib/libshp.so.$(LIBSHP_VERSION)
-	(cd /usr/local/lib && rm -f libshp.so.1 && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so.1)
-	(cd /usr/local/lib && rm -f libshp.so && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so)
-	chmod +x /usr/local/lib/libshp.so.$(LIBSHP_VERSION)
-	/usr/bin/install -c .libs/libshp.la /usr/local/lib/libshp.la
-	/usr/bin/install -c .libs/libshp.a /usr/local/lib/libshp.a
-	ranlib /usr/local/lib/libshp.a
-	chmod 644 /usr/local/lib/libshp.a
-	/bin/sh ./mkinstalldirs /usr/local/include/libshp
-	/usr/bin/install -c -m 644 shapefil.h /usr/local/include/libshp/shapefil.h
+lib:	libshp.a
+
+libshp.a:	$(LIBOBJ)
+	ar r libshp.a $(LIBOBJ)
+
+lib_install:	libshp.a
+	cp libshp.a $(PREFIX)/lib
+	cp shapefil.h $(PREFIX)/include
+
+bin_install:	$(SHPBIN)
+	cp $(SHPBIN) $(PREFIX)/bin
+
+install:	lib_install bin_install
+
diff --git a/README b/README
index ad5faa3..5ae71bb 100755
--- a/README
+++ b/README
@@ -7,20 +7,26 @@ Building on Unix
 1) Edit Makefile, and set CFLAGS, and CC macros as required for the
    target system.  Often the defaults will work fine.
 
-2) "type make" 
+2) type "make" 
 
 The result should be:
 
 Core shapelib support.  
   shpopen.o
   dbfopen.o
+  safileio.o
+  shptree.o
+  libshp.a
 
 Utility/demonstration programs:
-  shpcreate, shpdump, shpadd, dbfcreate, dbfdump, dbfadd
+  shpcreate, shpdump, shpadd, dbfcreate, dbfdump, dbfadd, shptreedump
 
-To test type:
+3) To test type:
   make test
 
+4) To libshp.a and the test binaries in /usr/local:
+  make install 
+
 
 Building on Windows
 -------------------
diff --git a/contrib/.cvsignore b/contrib/.cvsignore
index 5a4010b..81e44a9 100644
--- a/contrib/.cvsignore
+++ b/contrib/.cvsignore
@@ -7,3 +7,6 @@ dbfcat
 shpinfo
 shpfix
 shpcat
+Shape_PointInPoly
+shpproj
+shpsort
diff --git a/contrib/Makefile b/contrib/Makefile
index ab0ab13..9ae82f2 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -5,17 +5,17 @@
 # Endian: define either _LITTLE_ENDIAN or _BIG_ENDIAN
 ENDIAN	=	-D_LITTLE_ENDIAN
 
-CFLAGS	=	-g -I.. -DPROJ4 $(ENDIAN) -DDEBUG -DDEBUG2 
+CFLAGS	=	-g -I.. -I$(HOME)/bld/include -DPROJ4 $(ENDIAN) -DDEBUG -DDEBUG2 
 
-SHPOBJ	=	../shpopen.o ../dbfopen.o 
+SHPOBJ	=	../shpopen.o ../dbfopen.o ../safileio.o
 
-SHPGOBJ =	../shpopen.o ../dbfopen.o shpgeo.o
+SHPGOBJ =	../shpopen.o ../dbfopen.o ../safileio.o shpgeo.o
 
-GEOOBJ	=	./shpgeo.o -lm -lproj
+GEOOBJ	=	./shpgeo.o -lm -L$(HOME)/bld/lib -lproj
 
 default:	all
 
-all:	shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfinfo dbfcat shpinfo shpfix shpcat
+all:	shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfinfo dbfcat shpinfo shpfix shpcat Shape_PointInPoly shpsort
 
 clean:  
 	rm -f shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfcat dbfinfo shpinfo shpfix shpcat *.o
@@ -47,12 +47,19 @@ shpwkb:		shpwkb.c $(SHPGOBJ)
 shpproj: 	shpproj.c $(SHPGOBJ)
 	$(CC) $(CFLAGS) shpproj.c  $(SHPOBJ) $(GEOOBJ) -lm -lproj $(LINKOPT) -o shpproj
 
+shpsort:		shpsort.c $(SHPOBJ)
+	$(CC) $(CFLAGS) shpsort.c ${SHPOBJ} $(LINKOPT) -lm -o shpsort
+
 dbfinfo: 	dbfinfo.c $(SHPOBJ)
 	$(CC) $(CFLAGS) dbfinfo.c $(SHPOBJ) $(LINKOPT) -o dbfinfo
 
 dbfcat:		dbfcat.c $(SHPOBJ)
 	$(CC) $(CFLAGS) dbfcat.c $(SHPOBJ) $(LINKOPT) -o dbfcat
 
+Shape_PointInPoly:	Shape_PointInPoly.cpp $(SHPOBJ)
+	$(CXX) $(CFLAGS) Shape_PointInPoly.cpp $(SHPOBJ) $(LINKOPT) \
+		-o Shape_PointInPoly
+
 check:	testproj
 
 testproj: 
diff --git a/contrib/ShapeFileII.pas b/contrib/ShapeFileII.pas
index 4ddb26e..14dc0b1 100644
--- a/contrib/ShapeFileII.pas
+++ b/contrib/ShapeFileII.pas
@@ -1,6 +1,6 @@
 {
 /******************************************************************************
- * $Id: ShapeFileII.pas,v 1.2 2002/01/21 14:09:26 warmerda Exp $
+ * $Id: ShapeFileII.pas,v 1.3 2003-05-14 20:04:51 warmerda Exp $
  *
  * Project:  Shapelib
  * Purpose:  Delphi Pascal interface to Shapelib.
@@ -35,6 +35,9 @@
  ******************************************************************************
  *
  * $Log: ShapeFileII.pas,v $
+ * Revision 1.3  2003-05-14 20:04:51  warmerda
+ * Changed fpSHP and fpSHX to integer at suggestion of Ivan Lucena.
+ *
  * Revision 1.2  2002/01/21 14:09:26  warmerda
  * Fixed name.
  *
@@ -90,7 +93,7 @@ SHPBoundsArr = double;
 
 SHPInfo = record
     fpSHP,
-    fpSHX : FILE;
+    fpSHX : integer;
 
     nShapeType,
     nFileSize,
diff --git a/contrib/Shape_PointInPoly.cpp b/contrib/Shape_PointInPoly.cpp
new file mode 100644
index 0000000..32fd240
--- /dev/null
+++ b/contrib/Shape_PointInPoly.cpp
@@ -0,0 +1,238 @@
+/******************************************************************************
+ * $Id: Shape_PointInPoly.cpp,v 1.1 2004-01-09 16:47:57 fwarmerdam Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Commandline program to generate points-in-polygons from a 
+ *           shapefile as a shapefile.
+ * Author:   Marko Podgorsek, d-mon at siol.net
+ *
+ ******************************************************************************
+ * Copyright (c) 2004, Marko Podgorsek, d-mon at siol.net
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: Shape_PointInPoly.cpp,v $
+ * Revision 1.1  2004-01-09 16:47:57  fwarmerdam
+ * New
+ *
+ */
+
+static char rcsid[] = 
+  "$Id: Shape_PointInPoly.cpp,v 1.1 2004-01-09 16:47:57 fwarmerdam Exp $";
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <shapefil.h>
+
+#define MAXINTERSECTIONPOINTS 255
+
+enum loopDir {
+    kExterior,   
+    kInterior,
+    kError
+};
+
+struct DPoint2d
+{
+    DPoint2d() 
+	{
+            x = y = 0.0;
+	};
+    DPoint2d(double x, double y)
+	{
+            this->x = x;
+            this->y = y;
+	};
+    double x,y;
+};
+
+struct IntersectPoint
+{
+    IntersectPoint(void) 
+	{
+            x = y = 0.0;
+            boundry_nmb = 0;
+            loopdirection = kError;
+	};
+    double x,y;
+    int boundry_nmb;
+    loopDir loopdirection;
+};
+
+loopDir LoopDirection(DPoint2d *vertices, int vertsize)
+{
+    int i;
+    double sum = 0.0;
+    for(i=0;i<vertsize-1;i++)
+    {
+        sum += (vertices[i].x*vertices[i+1].y)-(vertices[i].y*vertices[i+1].x);
+    }
+
+    if(sum>0)
+        return kInterior;
+    else
+        return kExterior;
+}
+
+DPoint2d CreatePointInPoly(SHPObject *psShape, int quality)
+{
+    int i, j, k, end, vert, pointpos;
+    double part, dx, xmin, xmax, ymin, ymax, y, x3, x4, y3, y4, len, maxlen = 0;
+    DPoint2d *vertices;
+    loopDir direction;
+    IntersectPoint mp1, mp2, point1, point2, points[MAXINTERSECTIONPOINTS];
+
+    xmin = psShape->dfXMin;
+    ymin = psShape->dfYMin;
+    xmax = psShape->dfXMax;
+    ymax = psShape->dfYMax;
+    part = (ymax-ymin)/(quality+1);
+    dx = xmax-xmin;
+    for(i=0;i<quality;i++)
+    {
+        y = ymin+part*(i+1);
+        pointpos = 0;
+        for(j=0;j<psShape->nParts;j++)
+        {
+            if(j==psShape->nParts-1)
+                end = psShape->nVertices;
+            else
+                end = psShape->panPartStart[j+1];
+            vertices = new DPoint2d [end-psShape->panPartStart[j]];
+            for(k=psShape->panPartStart[j],vert=0;k<end;k++)
+            {
+                vertices[vert].x = psShape->padfX[k];
+                vertices[vert++].y = psShape->padfY[k];
+            }
+            direction = LoopDirection(vertices, vert);
+            for(k=0;k<vert-1;k++)
+            {
+                y3 = vertices[k].y;
+                y4 = vertices[k+1].y;
+                if((y3 >= y && y4 < y) || (y3 <= y && y4 > y)) //I check >= only once, because if it's not checked now (y3) it will be in the next iteration (which is y4 now)
+                {
+                    point1.boundry_nmb = j;
+                    point1.loopdirection = direction;
+                    x3 = vertices[k].x;
+                    x4 = vertices[k+1].x;
+                    if(y3==y)
+                    {
+                        point1.y = y3;
+                        point1.x = x3;
+                        if(direction == kInterior) //add point 2 times if the direction is interior, so that the final count of points is even
+                        {
+                            points[pointpos++]=point1;
+                        }
+                    }
+                    else
+                    {
+                        point1.x = xmin+(((((x4-x3)*(y-y3))-((y4-y3)*(xmin-x3)))/((y4-y3)*dx))*dx); //striped down calculation of intersection of 2 lines
+                        point1.y = y;
+                    }
+                    points[pointpos++]=point1;
+                }
+            }
+            delete [] vertices;
+        }
+
+        for(j=1;j<pointpos;j++) //sort the found intersection points by x value
+        {
+            for(k=j;k>0;k--)
+            {
+                if(points[k].x < points[k-1].x)
+                {
+                    point1 = points[k];
+                    points[k] = points[k-1];
+                    points[k-1] = point1;
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        for(j=0;j<pointpos-1;j++)
+        {
+            point1 = points[j];
+            point2 = points[j+1];
+            if((point1.loopdirection == kExterior         &&  //some checkings for valid point
+                point2.loopdirection == kExterior         &&
+                point1.boundry_nmb == point2.boundry_nmb  &&
+                j%2==0)                                   ||
+               (point1.loopdirection == kExterior        &&
+                point2.loopdirection == kInterior)        ||
+               (point1.loopdirection == kInterior        &&
+                point2.loopdirection == kExterior))
+            {
+                len = sqrt(pow(point1.x-point2.x, 2)+pow(point1.y-point2.y, 2));
+                if(len >= maxlen)
+                {
+                    maxlen = len;
+                    mp1 = point1;
+                    mp2 = point2;
+                }
+            }
+        }
+    }
+
+    return DPoint2d((mp1.x+mp2.x)*0.5, (mp1.y+mp2.y)*0.5);
+}
+
+int main(int argc, char* argv[])
+{
+    if(argc != 3)
+    {
+        printf("Usage: %s shpfile_path quality\n", argv[0]);
+        return 1;
+    }
+
+    int i, nEntities, quality;
+    SHPHandle hSHP;
+    SHPObject	*psShape;
+    DPoint2d pt;
+    quality = atoi(argv[2]);
+    hSHP = SHPOpen(argv[1], "rb");
+    SHPGetInfo(hSHP, &nEntities, NULL, NULL, NULL);
+
+    printf("PointInPoly v1.0, by Marko Podgorsek\n----------------\n");
+    for( i = 0; i < nEntities; i++ )
+    {
+        psShape = SHPReadObject( hSHP, i );
+        if(psShape->nSHPType == SHPT_POLYGON)
+        {
+            pt = CreatePointInPoly(psShape, quality);
+            printf("%d: x=%f y=%f\n",i, pt.x,pt.y);
+        }
+        SHPDestroyObject( psShape );
+    }
+
+    SHPClose(hSHP);
+
+    return 0;
+}
+
diff --git a/contrib/Shape_PointInPoly_README.txt b/contrib/Shape_PointInPoly_README.txt
new file mode 100644
index 0000000..dffe2eb
--- /dev/null
+++ b/contrib/Shape_PointInPoly_README.txt
@@ -0,0 +1,59 @@
+===============================================================================
+Project:  Shape_PoinInPoly
+Purpose:  Sample and the function for calculatin a point in a polygon 
+	  (complex,compound - it doesn't matter). Can be used for labeling.
+Author:   Copyright (c) 2004, Marko Podgorsek, d-mon at siol.net
+===============================================================================
+Requires: shapelib 1.2 (http://shapelib.maptools.org/)
+Tested and created on platform: 
+   Windows 2000 Professional
+   Visual Studio .NET 7.0
+   P4 2.4 GHz
+   1GB RAM
+
+I just found out about the ShapeLib, GDAL and OGR and I must say that they're 
+all great projects.
+I belive I'll use some of those libraries in the future. Right now I'm using 
+only shapelib.
+The thing that led me to the http://wwww.maptools.org was the need of finding 
+the point in poly...but as I found out that even OGR didn't support it. So 
+there I was. I was forced to make my own function. Well, it was fun. I learned
+a lot.
+I wrote this function for the Autodesk Autocad 2004 MPolygon, because there was
+no function to do this in the Object Arx SDK (the Acad programming SDK). Well, 
+it will be in the 2005 release...but, still. There is a function in the 
+Autodesk Map 2004 version...in the menu.
+Not usefull when you need the coordinates, not the point on the screen...
+So when the Acad version was done I was thinking of doing it on the Shape files,
+too. A little bit of changing the structures and variable
+types (so they're not using Object Arx) and I was done.
+And here it is....Contribution from me to the ShapeLib world :)...and maybe even
+OGR (a little bit of changing there).
+
+Some statistics:
+For about 69000 polygons in Autocad picture (.dwg files)
+Autodesk Map 2004 was creating centroids (the menu command) about 45s (1 scan 
+line)
+My function, with 3 scan lines took about 5s. And I was drawing the dots on the
+picture...
+
+-------------------------------------------------------------------------------
+DPoint2d CreatePointInPoly(SHPObject *psShape, int quality)
+
+The second parameter quality tell the function just how many rays shall it use
+to get the point. 
+quality = 3 works very well, but anything below 5 is good.
+This doesn't mean that the execution will slow down, but it just finds a good
+point. That's all.
+
+The qality shows on the compound objects (multiple poligons with more than one
+exterior loop) - if not enough rays, then there may be no centroid.
+Or the U shaped thin polygon, only the bootom (below the y center line) is fat.
+Autodesk Map with one scan line will create the centroid on one of the thin
+parts, because it only uses the y center line. If you have more rays, one will
+surely pass the fat area and centroid will be created there.
+
+-------------------------------------------------------------------------------
+Anyone using this function:
+Just send me an e-mail, so I'll see if I did anything good for the public.
+And you can send me e-mail with questions also.
diff --git a/contrib/csv2shp.c b/contrib/csv2shp.c
new file mode 100644
index 0000000..467eb68
--- /dev/null
+++ b/contrib/csv2shp.c
@@ -0,0 +1,558 @@
+/*
+csv2shp - converts a character delimited file to a ESRI shapefile
+Copyright (C) 2005 Springs Rescue Mission
+
+
+LICENSE
+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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+The GNU General Public License is also available from the web
+site <http://www.gnu.org>.
+
+
+GRATITUDE
+Like this program?  Donate at <http://springsrescuemission.org>.
+
+
+COMPILING INSTRUCTIONS
+This program was written and tested using Shapefile C Library version
+1.2.10 available at <http://shapelib.maptools.org>.
+
+To compile, copy csv2shp.c to the directory with Shapefile C Library.
+Then, compile Shapefile C library.  Then, run something like this:
+
+	gcc -pedantic -Wall -o csv2shp csv2shp.c -I. *o
+
+
+USAGE NOTES
+This program operates on single points only (not polygons or lines).
+
+The input file may be a .csv file (comma separated values) or tab-separated
+values, or it may be separated by any other character.  The first row must 
+contain column names.  There must be each a column named longitude and 
+latitude in the input file.
+
+The .csv parser does not understand text delimiters (e.g. quotation mark).
+It parses fields only by the given field delimiter (e.g. comma or tab).
+The program has not been tested with null values, and in this case, the
+behavior is undefined.  The program will not accept lines with a trailing 
+delimiter character.
+
+All columns (including longitude and latitude) in the input file are exported 
+to the .dbf file.
+
+The program attempts to find the best type (integer, decimal, string) and
+smallest size of the fields necessary for the .dbf file.
+
+
+SUPPORT
+Springs Rescue Mission does not offer any support for this program.
+
+
+CONTACT INFORMATION
+Springs Rescue Mission
+5 West Las Vegas St
+PO Box 2108
+Colorado Springs CO 80901
+Web: <http://springsrescuemission.org>
+Email: <http://springsrescuemission.org/email.php?recipient=webmaster>
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "shapefil.h"
+#include "regex.h"
+
+#define MAX_COLUMNS 30
+
+typedef struct column_t {
+	DBFFieldType eType;
+	int nWidth;
+	int nDecimals;
+} column;
+
+/* counts the number of occurances of the character in the string */
+int strnchr(const char *s, char c)
+{
+	int n = 0;
+	int x = 0;
+
+	for (; x < strlen(s); x++)
+	{
+		if (c == s[x])
+		{
+			n++;
+		}
+	}
+
+	return n;
+}
+
+/* Returns a field given by column n (0-based) in a character-
+   delimited string s */
+char * delimited_column(char *s, char delim, int n)
+{
+	static char szreturn[4096];
+	char szbuffer[4096]; /* a copy of s */
+	char * pchar;
+	int x;
+	char szdelimiter[2]; /* delim converted to string */
+
+	if (strnchr(s, delim) < n)
+	{
+		fprintf(stderr, "delimited_column: n is too large\n");
+		return NULL;
+	}
+
+	strcpy(szbuffer, s);
+	szdelimiter[0] = delim;
+	szdelimiter[1] = '\0';
+	x = 0;
+	pchar = strtok(szbuffer, szdelimiter);
+	while (x < n)
+	{	
+		pchar = strtok(NULL, szdelimiter);
+		x++;
+	}
+
+	if (NULL == pchar)
+	{
+		return NULL;
+	}
+
+	strcpy(szreturn, pchar);
+	return szreturn;
+}
+
+/* Determines the most specific column type.
+   The most specific types from most to least are integer, float, string.  */
+DBFFieldType str_to_fieldtype(const char *s)
+{
+	regex_t regex_i;
+	regex_t regex_d;
+
+	if (0 != regcomp(&regex_i, "^[0-9]+$", REG_NOSUB|REG_EXTENDED))
+	{
+		fprintf(stderr, "integer regex complication failed\n");
+		exit (EXIT_FAILURE);
+	}
+	
+	if (0 == regexec(&regex_i, s, 0, NULL, 0))
+	{
+		regfree(&regex_i);
+		return FTInteger;
+	}
+
+	regfree(&regex_i);
+
+	if (0 != regcomp(&regex_d, "^-?[0-9]+\\.[0-9]+$", REG_NOSUB|REG_EXTENDED))
+	{
+		fprintf(stderr, "integer regex complication failed\n");
+		exit (EXIT_FAILURE);
+	}
+
+	if (0 == regexec(&regex_d, s, 0, NULL, 0))
+	{
+		regfree(&regex_d);
+		return FTDouble;
+	}
+
+	regfree(&regex_d);
+
+	return FTString;
+}
+
+int float_width(const char *s)
+{
+	regex_t regex_d;
+	regmatch_t pmatch[2];
+	char szbuffer[4096];
+
+	if (0 != regcomp(&regex_d, "^(-?[0-9]+)\\.[0-9]+$", REG_EXTENDED))
+	{
+		fprintf(stderr, "integer regex complication failed\n");
+		exit (EXIT_FAILURE);
+	}
+
+	if (0 != regexec(&regex_d, s, 2, &pmatch[0], 0))
+	{
+		return -1;
+	}
+
+	strncpy(szbuffer, &s[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
+	szbuffer[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
+	regfree(&regex_d);
+
+	return strlen(szbuffer);
+}
+
+/* returns the field width */
+int str_to_nwidth(const char *s, DBFFieldType eType)
+{
+	switch (eType)
+	{
+		case FTString:
+		case FTInteger:
+		case FTDouble:
+			return strlen(s);
+
+		default:
+			fprintf(stderr, "str_to_nwidth: unexpected type\n");
+			exit (EXIT_FAILURE);
+	}
+}
+
+/* returns the number of decimals in a real number given as a string s */
+int str_to_ndecimals(const char *s)
+{
+	regex_t regex_d;
+	regmatch_t pmatch[2];
+	char szbuffer[4096];
+
+	if (0 != regcomp(&regex_d, "^-?[0-9]+\\.([0-9]+)$", REG_EXTENDED))
+	{
+		fprintf(stderr, "integer regex complication failed\n");
+		exit (EXIT_FAILURE);
+	}
+
+	if (0 != regexec(&regex_d, s, 2, &pmatch[0], 0))
+	{
+		return -1;
+	}
+
+	strncpy(szbuffer, &s[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
+	szbuffer[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
+
+	regfree(&regex_d);
+
+	return strlen(szbuffer);
+}
+
+/* returns true if f1 is more general than f2, otherwise false */
+int more_general_field_type(DBFFieldType t1, DBFFieldType t2)
+{
+	if (FTInteger == t2 && t1 != FTInteger)
+	{
+		return 1;
+	}
+
+	if (FTDouble == t2 && FTString == t1)
+	{
+		return 1;
+	}
+	
+	return 0;
+}
+
+void strip_crlf (char *line)
+{
+  /* remove trailing CR/LF */
+
+  if (strchr (line, 0x0D))
+    {
+      char *pszline;
+      pszline = strchr (line, 0x0D);
+      pszline[0] = '\0';
+    }
+
+  if (strchr (line, 0x0A))
+    {
+      char *pszline;
+      pszline = strchr (line, 0x0A);
+      pszline[0] = '\0';
+    }
+}
+
+int main( int argc, char ** argv )
+{
+	FILE *csv_f;
+	char sbuffer[4096];
+	char delimiter;
+	int n_columns; /* 1-based */
+	int n_line;
+	int n_longitude = -1; /* column with x, 0 based */
+	int n_latitude = -1; /* column with y, 0 based */
+	int x;
+	DBFHandle dbf_h;
+	SHPHandle shp_h;
+	column columns[MAX_COLUMNS + 1];
+
+	printf("csv2shp version 1, Copyright (C) 2005 Springs Rescue Mission\n");
+
+	if (4 != argc)
+	{
+		fprintf(stderr, "csv2shp comes with ABSOLUTELY NO WARRANTY; for details\n");
+		fprintf(stderr, "see csv2shp.c.  This is free software, and you are welcome\n");
+		fprintf(stderr, "to redistribute it under certain conditions; see csv2shp.c\n");
+		fprintf(stderr, "for details\n");
+		fprintf(stderr, "\n");
+		fprintf(stderr, "USAGE\n");
+		fprintf(stderr, "csv2shp csv_filename delimiter_character shp_filename\n");
+		fprintf(stderr, "   csv_filename\n");
+		fprintf(stderr, "     columns named longitude and latitude must exist\n");
+		fprintf(stderr, "   delimiter_character\n");
+		fprintf(stderr, "     one character only\n");
+		fprintf(stderr, "   shp_filename\n");
+		fprintf(stderr, "     base name, do not give the extension\n");
+		return EXIT_FAILURE;
+	}
+
+	if (strlen(argv[2]) > 1)
+	{
+		fprintf(stderr, "delimiter must be one character in length\n");
+		return EXIT_FAILURE;
+	}
+
+	delimiter = argv[2][0];
+
+	csv_f = fopen(argv[1], "r");
+
+	if (NULL == csv_f)
+	{
+		perror("could not open csv file");
+		exit (EXIT_FAILURE);
+	}
+
+	fgets(sbuffer, 4000, csv_f);
+
+	/* check first row */
+
+	strip_crlf(sbuffer);
+
+	if (delimiter == sbuffer[strlen(sbuffer)- 1])
+	{
+		fprintf(stderr, "lines must not end with the delimiter character\n");
+		return EXIT_FAILURE;
+
+	}
+
+	/* count columns and verify consistency*/
+
+	n_columns = strnchr(sbuffer, delimiter);
+
+	if (n_columns > MAX_COLUMNS)
+	{
+		fprintf(stderr, "too many columns, maximum is %i\n", MAX_COLUMNS);
+		return EXIT_FAILURE;
+	}
+
+	n_line = 1;
+
+	while (!feof(csv_f))
+	{
+		n_line++;
+		fgets(sbuffer, 4000, csv_f);
+		if (n_columns != strnchr(sbuffer, delimiter))
+		{
+			fprintf(stderr, "Number of columns on row %i does not match number of columns on row 1\n", n_columns);
+			return EXIT_FAILURE;
+		}
+	}
+
+	/* identify longitude and latitude columns */
+
+	fseek(csv_f, 0, SEEK_SET);
+	fgets(sbuffer, 4000, csv_f);
+	strip_crlf(sbuffer);
+
+	for (x = 0; x <= n_columns; x++)
+	{	
+		if (0 == strcasecmp("Longitude", delimited_column(sbuffer, delimiter, x)))
+		{
+			n_longitude = x;
+		}
+
+		if (0 == strcasecmp("Latitude", delimited_column(sbuffer, delimiter, x)))
+		{
+			n_latitude = x;
+		}
+	}
+
+#ifdef DEBUG
+	printf("debug lat/long = %i/%i\n", n_latitude, n_longitude);
+#endif
+
+	if (-1 == n_longitude || -1 == n_latitude)
+	{
+		fprintf(stderr, "The header row must define one each a column named longitude and latitude\n");
+		return EXIT_FAILURE;
+	}
+
+	/* determine best fit for each column */
+
+	printf ("Anaylzing column types...\n");
+
+#ifdef DEBUG
+	printf("debug: string type = %i\n", FTString);
+	printf("debug: int type = %i\n", FTInteger);
+	printf("debug: double type = %i\n", FTDouble);
+#endif
+	for (x = 0; x <= n_columns; x++)
+	{	
+#ifdef DEBUG
+		printf("debug: examining column %i\n", x);
+#endif
+		columns[x].eType = FTInteger;
+		columns[x].nWidth = 2;
+		columns[x].nDecimals = 0;
+	
+		fseek(csv_f, 0, SEEK_SET);
+		fgets(sbuffer, 4000, csv_f);
+
+		while (!feof(csv_f))
+		{
+			char szfield[4096];
+#ifdef DEBUG
+			printf ("column %i, type = %i, w = %i, d = %i\n", x, columns[x].eType, columns[x].nWidth, columns[x].nDecimals);
+#endif
+			if (NULL == fgets(sbuffer, 4000, csv_f))
+			{
+				if (!feof(csv_f))
+				{
+					fprintf(stderr, "error during fgets()\n");
+				}
+				continue;
+			}
+			strcpy(szfield, delimited_column(sbuffer, delimiter, x));
+			if (more_general_field_type(str_to_fieldtype(szfield), columns[x].eType))
+			{
+				columns[x].eType = str_to_fieldtype(szfield);
+				columns[x].nWidth = 2;
+				columns[x].nDecimals = 0;
+				fseek(csv_f, 0, SEEK_SET);
+				fgets(sbuffer, 4000, csv_f);
+				continue;
+			}
+			if (columns[x].nWidth < str_to_nwidth(szfield, columns[x].eType))
+			{
+				columns[x].nWidth = str_to_nwidth(szfield, columns[x].eType);
+			}
+			if (FTDouble == columns[x].eType && columns[x].nDecimals < str_to_ndecimals(szfield))
+			{
+				columns[x].nDecimals = str_to_ndecimals(szfield);
+			}
+
+		}
+	}
+
+
+	/* initilize output files */
+
+	printf ("Initializing output files...\n");
+
+	shp_h = SHPCreate(argv[3], SHPT_POINT);
+
+	dbf_h = DBFCreate(argv[3]);
+
+	if (NULL == dbf_h)
+	{
+		fprintf(stderr, "DBFCreate failed\n");
+		exit (EXIT_FAILURE);
+	}
+
+	fseek(csv_f, 0, SEEK_SET);
+	fgets(sbuffer, 4000, csv_f);
+	strip_crlf(sbuffer);
+
+	for (x = 0; x <= n_columns; x++)
+	{	
+#ifdef DEBUG
+		printf ("debug: final: column %i, type = %i, w = %i, d = %i, name=|%s|\n", x, columns[x].eType, columns[x].nWidth, columns[x].nDecimals, delimited_column(sbuffer, delimiter, x));
+#endif
+		if (-1 == DBFAddField(dbf_h, delimited_column(sbuffer, delimiter, x), columns[x].eType, columns[x].nWidth, columns[x].nDecimals))
+		{
+			fprintf(stderr, "DBFFieldAdd failed column %i\n", x + 1);
+			exit (EXIT_FAILURE);
+		}
+
+	}
+
+	/* write data */
+
+	printf ("Writing data...\n");
+
+	fseek(csv_f, 0, SEEK_SET);
+	fgets(sbuffer, 4000, csv_f); /* skip header */
+
+	n_columns = strnchr(sbuffer, delimiter);
+	n_line = 1;
+
+	while (!feof(csv_f))
+	{
+		SHPObject * shp;
+		double x_pt;
+		double y_pt;
+		int shp_i;
+
+		n_line++;
+		fgets(sbuffer, 4000, csv_f);
+		
+		/* write to shape file */
+		x_pt = atof(delimited_column(sbuffer, delimiter, n_longitude));
+		y_pt = atof(delimited_column(sbuffer, delimiter, n_latitude));
+
+#ifdef DEBUG
+		printf("debug: sbuffer=%s", sbuffer);
+		printf("debug: x,y = %f, %f\n", x_pt, y_pt);
+#endif
+
+		shp = SHPCreateSimpleObject(SHPT_POINT, 1, &x_pt, &y_pt, NULL);
+		shp_i = SHPWriteObject(shp_h, -1, shp);
+		SHPDestroyObject(shp);
+
+		/* write to dbf */
+
+		for (x = 0; x <= n_columns; x++)
+		{	
+			char szfield[4096];
+			int b;
+
+			strcpy(szfield, delimited_column(sbuffer, delimiter, x));
+
+			switch (columns[x].eType)
+			{
+				case FTInteger:
+					b = DBFWriteIntegerAttribute(dbf_h, shp_i, x, atoi(szfield));
+					break;
+				case FTDouble:
+					b = DBFWriteDoubleAttribute(dbf_h, shp_i, x, atof(szfield));
+					break;
+				case FTString:
+					b = DBFWriteStringAttribute(dbf_h, shp_i, x, szfield);
+					break;
+				default:
+					fprintf(stderr, "unexpected column type %i in column %i\n", columns[x].eType, x);
+			}
+			
+			if (!b)
+			{
+				fprintf(stderr, "DBFWrite*Attribute failed\n");
+				exit (EXIT_FAILURE);
+			}
+		}
+	}
+
+	/* finish up */
+
+	SHPClose(shp_h);
+	
+        DBFClose(dbf_h);
+
+	return EXIT_SUCCESS;
+}
diff --git a/contrib/dbfcat.c b/contrib/dbfcat.c
index c03046d..2c4eb9f 100644
--- a/contrib/dbfcat.c
+++ b/contrib/dbfcat.c
@@ -4,7 +4,10 @@
  * This code is in the public domain.
  *
  * $Log: dbfcat.c,v $
- * Revision 1.1  1999/05/26 02:56:31  candrsn
+ * Revision 1.2  2011-07-24 03:17:46  fwarmerdam
+ * include string.h and stdlib.h where needed in contrib (#2146)
+ *
+ * Revision 1.1  1999-05-26 02:56:31  candrsn
  * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
  *
  * Revision 1.3  1995/10/21  03:15:01  warmerda
@@ -16,8 +19,10 @@
  */
 
 static char rcsid[] = 
-  "$Id: dbfcat.c,v 1.1 1999/05/26 02:56:31 candrsn Exp $";
+  "$Id: dbfcat.c,v 1.2 2011-07-24 03:17:46 fwarmerdam Exp $";
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 
 int main( int argc, char ** argv )
diff --git a/contrib/dbfinfo.c b/contrib/dbfinfo.c
index a251d61..07efb82 100644
--- a/contrib/dbfinfo.c
+++ b/contrib/dbfinfo.c
@@ -10,13 +10,17 @@
  * 
  *
  * $Log: dbfinfo.c,v $
- * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * Revision 1.3  2011-07-24 03:17:46  fwarmerdam
+ * include string.h and stdlib.h where needed in contrib (#2146)
+ *
+ * Revision 1.2  1999-05-26 02:56:31  candrsn
  * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
  *
  * 
  */
 
-
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 
 int main( int argc, char ** argv )
diff --git a/contrib/makefile.vc b/contrib/makefile.vc
index ff3ce16..f376f64 100644
--- a/contrib/makefile.vc
+++ b/contrib/makefile.vc
@@ -1,9 +1,8 @@
-PROJ_DIR = 	D:\warmerda\proj
 
-CFLAGS	=	/I.. /I$(PROJ_DIR)\src /D_LITTLE_ENDIAN -DPROJ4 
+CFLAGS	=	/Ox /MD /nologo /I.. /IC:\OSGeo4W\include \
+		/D_LITTLE_ENDIAN -DPROJ4 
 
-LINKARGS =	shpgeo.obj ..\shpopen.obj ..\dbfopen.obj \
-		D:\warmerda\proj\src\proj_i.lib
+LINKARGS =	..\shapelib_i.lib C:\OSGeo4W\lib\proj_i.lib
 
 default:	all
 
@@ -11,19 +10,25 @@ all:	shpcat.exe shpcentrd.exe shpdxf.exe shpinfo.exe shpproj.exe
 
 shpcat.exe:	shpcat.obj shpgeo.obj 
 	$(CC) $(CFLAGS) shpcat.obj  $(LINKARGS) 
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
 shpcentrd.exe:	shpcentrd.obj shpgeo.obj 
-	$(CC) $(CFLAGS) shpcentrd.obj  $(LINKARGS) 
+	$(CC) $(CFLAGS) shpcentrd.obj  shpgeo.obj $(LINKARGS) 
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
 shpproj.exe:	shpproj.obj shpgeo.obj 
-	$(CC) $(CFLAGS) shpproj.obj  $(LINKARGS) 
+	$(CC) $(CFLAGS) shpproj.obj shpgeo.obj $(LINKARGS) 
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
 shpdxf.exe:	shpdxf.obj shpgeo.obj 
 	$(CC) $(CFLAGS) shpdxf.obj  $(LINKARGS) 
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
 shpinfo.exe:	shpinfo.obj shpgeo.obj 
 	$(CC) $(CFLAGS) shpinfo.obj  $(LINKARGS) 
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
 clean:
-	del *.obj *.exe
-
+	-del *.obj
+	-del *.exe
+	-del *.manifest
diff --git a/contrib/shpcat.c b/contrib/shpcat.c
index b105fd5..d4c32df 100644
--- a/contrib/shpcat.c
+++ b/contrib/shpcat.c
@@ -31,7 +31,10 @@
  *
  */
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
+
 int dbfcat_main( int argc, char ** argv );
 
 int main( int argc, char ** argv )
diff --git a/contrib/shpcentrd.c b/contrib/shpcentrd.c
index d008603..8156b9e 100644
--- a/contrib/shpcentrd.c
+++ b/contrib/shpcentrd.c
@@ -28,7 +28,10 @@
  *
  *
  * $Log: shpcentrd.c,v $
- * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * Revision 1.3  2011-07-24 03:17:46  fwarmerdam
+ * include string.h and stdlib.h where needed in contrib (#2146)
+ *
+ * Revision 1.2  1999-05-26 02:56:31  candrsn
  * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
  *
  *
@@ -43,6 +46,8 @@
  *      Cy = sum (y dArea ) / Total Area
  */           
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 #include "shpgeo.h"
 
diff --git a/contrib/shpdata.c b/contrib/shpdata.c
index ba10337..e401b6e 100644
--- a/contrib/shpdata.c
+++ b/contrib/shpdata.c
@@ -26,7 +26,7 @@
  *
  *
  * $Log: shpdata.c,v $
- * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * Revision 1.2  1999-05-26 02:56:31  candrsn
  * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
  *
  *
diff --git a/contrib/shpdxf.c b/contrib/shpdxf.c
index 4a76b8f..2377809 100644
--- a/contrib/shpdxf.c
+++ b/contrib/shpdxf.c
@@ -37,9 +37,10 @@
  *
  */
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 
-
 #define FLOAT_PREC "%16.5f\r\n"
 
 void dxf_hdr (x1,y1,x2,y2,df)
diff --git a/contrib/shpfix.c b/contrib/shpfix.c
index 2c66ece..1ed73a3 100644
--- a/contrib/shpfix.c
+++ b/contrib/shpfix.c
@@ -34,6 +34,8 @@
  *
  */
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 
 int main( int argc, char ** argv )
diff --git a/contrib/shpgeo.c b/contrib/shpgeo.c
index 9f1d59d..09d5ff6 100644
--- a/contrib/shpgeo.c
+++ b/contrib/shpgeo.c
@@ -32,6 +32,21 @@
  * use -DPROJ4 to compile in Projection support
  *
  * $Log: shpgeo.c,v $
+ * Revision 1.13  2011-07-24 03:17:46  fwarmerdam
+ * include string.h and stdlib.h where needed in contrib (#2146)
+ *
+ * Revision 1.12  2007-09-03 23:17:46  fwarmerdam
+ * fix SHPDimension() function
+ *
+ * Revision 1.11  2006/11/06 20:45:58  fwarmerdam
+ * Fixed SHPProject.
+ *
+ * Revision 1.10  2006/11/06 20:44:58  fwarmerdam
+ * SHPProject() uses pj_transform now
+ *
+ * Revision 1.9  2006/01/25 15:33:50  fwarmerdam
+ * fixed ppsC assignment maptools bug 1263
+ *
  * Revision 1.8  2002/01/15 14:36:56  warmerda
  * upgrade to use proj_api.h
  *
@@ -55,6 +70,8 @@
  *
  */
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 
 #ifndef NAN
@@ -147,41 +164,31 @@ static void * SfRealloc( void * pMem, int nNewSize )
  * **************************************************************************/ 
 int SHPProject ( SHPObject *psCShape, projPJ inproj, projPJ outproj ) {
 #ifdef	PROJ4
-   int	j;
-   projUV   p;    /* struct { double u, double v } */
 
-   /* for each vertex project it and stuff the projeted point back into 	*/
-   /*	same SHPObject.  Proj assumes data is in radians so convert it.		*/
-   /*   Proj will convert Geographic -> <proj> and <proj> -> Geographic		*/
-   /*	so <proj1> -> <proj2> requires bouncing though geographic			*/
-   
-   for ( j=0; j < psCShape->nVertices; j++ ) {
-     p.u = psCShape->padfX[j];
-     p.v = psCShape->padfY[j];
+    int    j;
 
-     if ( inproj )
-       p = pj_inv ( p, inproj );
-     else
-      { p.u *= DEG_TO_RAD;
-        p.v *= DEG_TO_RAD;
-      }
+    if ( pj_is_latlong(inproj) ) {
+        for(j=0; j < psCShape->nVertices; j++) {
+            psCShape->padfX[j] *= DEG_TO_RAD;
+            psCShape->padfY[j] *= DEG_TO_RAD;
+        }
+    }   
 
-     if ( outproj ) 
-       p = pj_fwd ( p, outproj );
-     else
-     { p.u *= RAD_TO_DEG;
-       p.v *= RAD_TO_DEG;
-     } 
+    pj_transform(inproj, outproj, psCShape->nVertices, 0, psCShape->padfX,
+                 psCShape->padfY, NULL);
 
-     psCShape->padfX[j] = p.u;
-     psCShape->padfY[j] = p.v;
-   }
-   
-   /* Recompute new Extents of projected Object								*/
-   SHPComputeExtents ( psCShape );
+    if ( pj_is_latlong(outproj) ) {
+        for(j=0; j < psCShape->nVertices; j++) {
+            psCShape->padfX[j] *= RAD_TO_DEG;
+            psCShape->padfY[j] *= RAD_TO_DEG;
+        }
+    }   
+
+    /* Recompute new Extents of projected Object								*/
+    SHPComputeExtents ( psCShape );
 #endif  
 
-   return ( 1 );
+    return ( 1 );
 }
 
 
@@ -543,8 +550,8 @@ int SHPWriteOGisPolygon ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
    nextring = 0;
    cParts=0;
    while ( nextring >= 0 ) {
-     (SHPObject*) ppsC[cParts] = SHPUnCompound ( psCShape, &nextring ); 
-     cParts++;
+       ppsC[cParts] = SHPUnCompound ( psCShape, &nextring ); 
+       cParts++;
     }
    
 #ifdef DEBUG2
@@ -828,22 +835,22 @@ int SHPDimension ( int SHPType ) {
     dimension = 0;
       
     switch ( SHPType ) {
-    	case  SHPT_POINT       :	dimension = SHPD_POINT ;
-    	case  SHPT_ARC         :	dimension = SHPD_LINE;
-    	case  SHPT_POLYGON     :	dimension = SHPD_AREA;    	
-    	case  SHPT_MULTIPOINT  :	dimension = SHPD_POINT;    	
-    	case  SHPT_POINTZ      :	dimension = SHPD_POINT | SHPD_Z;    	
-    	case  SHPT_ARCZ        :	dimension = SHPD_LINE | SHPD_Z;
-    	case  SHPT_POLYGONZ    :	dimension = SHPD_AREA | SHPD_Z;
-    	case  SHPT_MULTIPOINTZ :	dimension = SHPD_POINT | SHPD_Z;    	
-    	case  SHPT_POINTM      :	dimension = SHPD_POINT | SHPD_MEASURE;    	
-    	case  SHPT_ARCM        :	dimension = SHPD_LINE | SHPD_MEASURE;
-    	case  SHPT_POLYGONM    :	dimension = SHPD_AREA | SHPD_MEASURE;
-    	case  SHPT_MULTIPOINTM :	dimension = SHPD_POINT | SHPD_MEASURE;   	 	
-    	case  SHPT_MULTIPATCH  :	dimension = SHPD_AREA;  
+      case  SHPT_POINT       :	dimension = SHPD_POINT; break;
+      case  SHPT_ARC         :	dimension = SHPD_LINE; break;  
+      case  SHPT_POLYGON     :	dimension = SHPD_AREA; break;   	
+      case  SHPT_MULTIPOINT  :	dimension = SHPD_POINT; break;
+      case  SHPT_POINTZ      :	dimension = SHPD_POINT | SHPD_Z; break;
+      case  SHPT_ARCZ        :	dimension = SHPD_LINE | SHPD_Z; break;
+      case  SHPT_POLYGONZ    :	dimension = SHPD_AREA | SHPD_Z; break;
+      case  SHPT_MULTIPOINTZ :	dimension = SHPD_POINT | SHPD_Z; break;
+      case  SHPT_POINTM      :	dimension = SHPD_POINT | SHPD_MEASURE; break;
+      case  SHPT_ARCM        :	dimension = SHPD_LINE | SHPD_MEASURE; break;
+      case  SHPT_POLYGONM    :	dimension = SHPD_AREA | SHPD_MEASURE; break;
+      case  SHPT_MULTIPOINTM :	dimension = SHPD_POINT | SHPD_MEASURE; break;
+      case  SHPT_MULTIPATCH  :	dimension = SHPD_AREA; break;
     }
 
-   return ( dimension );
+    return ( dimension );
 }
 
 
diff --git a/contrib/shpgeo.h b/contrib/shpgeo.h
index 02276b1..504812c 100644
--- a/contrib/shpgeo.h
+++ b/contrib/shpgeo.h
@@ -27,7 +27,7 @@
  *
  *
  * $Log: shpgeo.h,v $
- * Revision 1.3  2002/01/15 14:36:56  warmerda
+ * Revision 1.3  2002-01-15 14:36:56  warmerda
  * upgrade to use proj_api.h
  *
  * Revision 1.2  1999/05/26 02:56:31  candrsn
diff --git a/contrib/shpinfo.c b/contrib/shpinfo.c
index 4859e49..f1ae3e8 100644
--- a/contrib/shpinfo.c
+++ b/contrib/shpinfo.c
@@ -27,7 +27,10 @@
  * 
  *
  * $Log: shpinfo.c,v $
- * Revision 1.3  2002/04/15 21:33:03  warmerda
+ * Revision 1.4  2011-07-24 03:17:46  fwarmerdam
+ * include string.h and stdlib.h where needed in contrib (#2146)
+ *
+ * Revision 1.3  2002-04-15 21:33:03  warmerda
  * Avoid dereference arrays.
  *
  * Revision 1.2  2002/04/15 18:40:31  warmerda
@@ -39,6 +42,8 @@
  *
  */
 
+#include <stdlib.h>
+#include <string.h>
 #include "shapefil.h"
 
 int main( int argc, char ** argv )
diff --git a/contrib/shpproj.c b/contrib/shpproj.c
index 0759723..231c7f7 100644
--- a/contrib/shpproj.c
+++ b/contrib/shpproj.c
@@ -20,7 +20,7 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
- *******************************************************************************
+ ******************************************************************************
  *
  * requires shapelib 1.2
  *   gcc shpproj ../shpopen.o ../dbfopen.o shpgeo.o -lm -lproj -o shpproj
@@ -33,7 +33,10 @@
  * SHPGeo must be compiled with -DPROJ4 support
  *
  * $Log: shpproj.c,v $
- * Revision 1.9  2002/01/15 14:37:08  warmerda
+ * Revision 1.10  2011-07-24 03:17:46  fwarmerdam
+ * include string.h and stdlib.h where needed in contrib (#2146)
+ *
+ * Revision 1.9  2002-01-15 14:37:08  warmerda
  * upgrade to use proj_api.h
  *
  * Revision 1.8  2002/01/11 15:47:26  warmerda
@@ -52,9 +55,11 @@
  */
 
 
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
 #include "shapefil.h"
 #include "shpgeo.h"
-#include <stdarg.h>
 
 int main( int argc, char ** argv )
 {
diff --git a/contrib/shpsort.c b/contrib/shpsort.c
new file mode 100644
index 0000000..ae0bf6f
--- /dev/null
+++ b/contrib/shpsort.c
@@ -0,0 +1,605 @@
+/******************************************************************************
+ * Copyright (c) 2004, Eric G. Miller
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * shpsort
+ *
+ * Rewrite a shapefile sorted by a field or by the geometry.  For polygons,
+ * sort by area, for lines sort by length and do nothing for all others.
+ *
+ * $Log: shpsort.c,v $
+ * Revision 1.3  2004-07-06 21:23:17  fwarmerdam
+ * minor const warning fix
+ *
+ * Revision 1.2  2004/07/06 21:20:49  fwarmerdam
+ * major upgrade .. sort on multiple fields
+ *
+ * Revision 1.4  2004/06/30 18:19:53  emiller
+ * handle POINTZ, POINTM
+ *
+ * Revision 1.3  2004/06/30 17:40:32  emiller
+ * major rewrite allows sorting on multiple fields.
+ *
+ * Revision 1.2  2004/06/23 23:19:58  emiller
+ * use tuple copy, misc changes
+ *
+ * Revision 1.1  2004/06/23 21:38:17  emiller
+ * Initial revision
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include "shapefil.h"
+
+enum FieldOrderEnum {DESCENDING, ASCENDING};
+enum FieldTypeEnum {
+  FIDType = -2, 
+  SHPType = -1, 
+  StringType = FTString,
+  LogicalType = FTLogical,
+  IntegerType = FTInteger,
+  DoubleType = FTDouble
+};
+
+struct DataUnion {
+  int null;
+  union {
+    int i;
+    double d;
+    char *s;
+  } u;
+};
+
+struct DataStruct {
+  int record;
+  struct DataUnion *value;
+};
+
+/* 
+   globals used in sorting, each element could have a pointer to
+   a single data struct, but that's still nShapes pointers more
+   memory.  Alternatively, write a custom sort rather than using
+   library qsort.
+*/
+int nFields;
+int *fldIdx;
+int *fldOrder;
+int *fldType;
+int shpType;
+int nShapes;
+
+static struct DataStruct * build_index (SHPHandle shp, DBFHandle dbf);
+static char * dupstr (const char *);
+static void copy_related (const char *inName, const char *outName, 
+			  const char *old_ext, const char *new_ext);
+static char ** split(const char *arg, const char *delim);
+static int compare(const void *, const void *);
+static double area2d_polygon (int n, double *x, double *y);
+static double shp_area (SHPObject *feat);
+static double length2d_polyline (int n, double *x, double *y);
+static double shp_length (SHPObject *feat);
+
+int main (int argc, char *argv[]) {
+
+  SHPHandle  inSHP, outSHP;
+  DBFHandle  inDBF, outDBF;
+  int        len; 
+  int        i;
+  char       **fieldNames;
+  char       **strOrder = 0;
+  struct DataStruct *index;
+  int        width;
+  int        decimals;
+  SHPObject  *feat;
+  void       *tuple;
+
+  if (argc < 4) {
+    printf("USAGE: shpsort <infile> <outfile> <field[;...]> [<(ASCENDING|DESCENDING)[;...]>]\n");
+    exit(EXIT_FAILURE);
+  }
+
+  inSHP = SHPOpen (argv[1], "rb");
+  if (!inSHP) {
+    fputs("Couldn't open shapefile for reading!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+  SHPGetInfo(inSHP, &nShapes, &shpType, NULL, NULL);
+
+  /* If we can open the inSHP, open its DBF */
+  inDBF = DBFOpen (argv[1], "rb");
+  if (!inDBF) {
+    fputs("Couldn't open dbf file for reading!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+
+  /* Parse fields and validate existence */
+  fieldNames = split(argv[3], ";");
+  if (!fieldNames) {
+    fputs("ERROR: parsing field names!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+  for (nFields = 0; fieldNames[nFields] ; nFields++) {
+    continue;
+  }
+
+  fldIdx = malloc(sizeof *fldIdx * nFields);
+  if (!fldIdx) {
+    fputs("malloc failed!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+  for (i = 0; i < nFields; i++) {
+    len = (int)strlen(fieldNames[i]);
+    while(len > 0) {
+      --len;
+      fieldNames[i][len] = (char)toupper((unsigned char)fieldNames[i][len]); 
+    }
+    fldIdx[i] = DBFGetFieldIndex(inDBF, fieldNames[i]);
+    if (fldIdx[i] < 0) {
+      /* try "SHAPE" */
+      if (strcmp(fieldNames[i], "SHAPE") == 0) {
+	fldIdx[i] = -1;
+      }
+      else if (strcmp(fieldNames[i], "FID") == 0) {
+	fldIdx[i] = -2;
+      }
+      else {
+	fprintf(stderr, "ERROR: field '%s' not found!\n", fieldNames[i]);
+	exit(EXIT_FAILURE);
+      }
+    }
+  }
+
+
+  /* set up field type array */
+  fldType = malloc(sizeof *fldType * nFields);
+  if (!fldType) {
+    fputs("malloc failed!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+  for (i = 0; i < nFields; i++) {
+    if (fldIdx[i] < 0) {
+      fldType[i] = fldIdx[i];
+    }
+    else {
+      fldType[i] = DBFGetFieldInfo(inDBF, fldIdx[i], NULL, &width, &decimals);
+      if (fldType[i] == FTInvalid) {
+	fputs("Unrecognized field type in dBASE file!\n", stderr);
+	exit(EXIT_FAILURE);
+      }
+    }
+  }
+
+
+  /* set up field order array */
+  fldOrder = malloc(sizeof *fldOrder * nFields);
+  if (!fldOrder) {
+    fputs("malloc failed!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+  for (i = 0; i < nFields; i++) {
+    /* default to ascending order */
+    fldOrder[i] = ASCENDING;
+  }
+  if (argc > 4) {
+    strOrder = split(argv[4], ";");
+    if (!strOrder) {
+      fputs("ERROR: parsing fields ordering!\n", stderr);
+      exit(EXIT_FAILURE);
+    }
+    for (i = 0; i < nFields && strOrder[i]; i++) {
+      if (strcmp(strOrder[i], "DESCENDING") == 0) {
+	fldOrder[i] = DESCENDING;
+      }
+    }
+  }
+
+  /* build the index */
+  index = build_index (inSHP, inDBF);
+
+  /* Create output shapefile */
+  outSHP = SHPCreate(argv[2], shpType);
+  if (!outSHP) {
+    fprintf(stderr, "%s:%d: couldn't create output shapefile!\n",
+	    __FILE__, __LINE__);
+    exit(EXIT_FAILURE);
+  }
+  
+  /* Create output dbf */
+  outDBF = DBFCloneEmpty(inDBF, argv[2]);
+  if (!outDBF) {
+    fprintf(stderr, "%s:%d: couldn't create output dBASE file!\n",
+	    __FILE__, __LINE__);
+    exit(EXIT_FAILURE);
+  }
+
+  /* Copy projection file, if any */
+  copy_related(argv[1], argv[2], ".shp", ".prj");
+
+  /* Copy metadata file, if any */
+  copy_related(argv[1], argv[2], ".shp", ".shp.xml");
+
+  /* Write out sorted results */
+  for (i = 0; i < nShapes; i++) {
+    feat = SHPReadObject(inSHP, index[i].record);
+    if (SHPWriteObject(outSHP, -1, feat) < 0) {
+      fprintf(stderr, "%s:%d: error writing shapefile!\n", __FILE__, __LINE__);
+      exit(EXIT_FAILURE);
+    }
+    tuple = (void *) DBFReadTuple(inDBF, index[i].record);
+    if (DBFWriteTuple(outDBF, i, tuple) < 0) {
+      fprintf(stderr, "%s:%d: error writing dBASE file!\n", __FILE__, __LINE__);
+      exit(EXIT_FAILURE);
+    }
+  }
+  SHPClose(inSHP);
+  SHPClose(outSHP);
+  DBFClose(inDBF);
+  DBFClose(outDBF);
+
+  return EXIT_SUCCESS;
+
+}
+
+static char ** split(const char *arg, const char *delim)
+{
+  char *copy = dupstr(arg);
+  char *cptr = copy;
+  char **result = NULL;
+  char **tmp;
+  int i = 0;
+
+  for (cptr = strtok(copy, delim); cptr; cptr = strtok(NULL, delim)) {
+    tmp = realloc (result, sizeof *result * (i + 1));
+    if (!tmp && result) {
+      while (i > 0) {
+	free(result[--i]);
+      }
+      free(result);
+      free(copy);
+      return NULL;
+    }
+    result = tmp;
+    result[i++] = dupstr(cptr);
+  }
+
+  free(copy);
+
+  if (i) {
+    tmp = realloc(result, sizeof *result * (i + 1));
+    if (!tmp) {
+      while (i > 0) {
+	free(result[--i]);
+      }
+      free(result);
+      free(copy);
+      return NULL;
+    }
+    result = tmp;
+    result[i++] = NULL;
+  }
+
+  return result;
+}
+
+
+static void copy_related (const char *inName, const char *outName, 
+			  const char *old_ext, const char *new_ext) 
+{
+  char *in;
+  char *out;
+  FILE *inFile;
+  FILE *outFile;
+  int  c;
+  size_t name_len = strlen(inName);
+  size_t old_len  = strlen(old_ext); 
+  size_t new_len  = strlen(new_ext);
+
+  in = malloc(name_len - old_len + new_len + 1);
+  strncpy(in, inName, (name_len - old_len));
+  strcpy(&in[(name_len - old_len)], new_ext);
+  inFile = fopen(in, "rb");
+  if (!inFile) {
+    free(in);
+    return;
+  }
+  name_len = strlen(outName);
+  out = malloc(name_len - old_len + new_len + 1);
+  strncpy(out, outName, (name_len - old_len));
+  strcpy(&out[(name_len - old_len)], new_ext);
+  outFile = fopen(out, "wb");
+  if (!out) {
+    fprintf(stderr, "%s:%d: couldn't copy related file!\n",
+	    __FILE__, __LINE__);
+    free(in);
+    free(out);
+    return;
+  }
+  while ((c = fgetc(inFile)) != EOF) {
+    fputc(c, outFile);
+  }
+  fclose(inFile);
+  fclose(outFile);
+  free(in);
+  free(out);
+}
+
+static char * dupstr (const char *src)
+{
+  char *dst = malloc(strlen(src) + 1);
+  char *cptr;
+  if (!dst) {
+    fprintf(stderr, "%s:%d: malloc failed!\n", __FILE__, __LINE__);
+    exit(EXIT_FAILURE);
+  }
+  cptr = dst;
+  while ((*cptr++ = *src++))
+    ;
+  return dst;
+}
+
+#ifdef DEBUG
+static void PrintDataStruct (struct DataStruct *data) {
+  int i, j;
+  for (i = 0; i < nShapes; i++) {
+    printf("data[%d] {\n", i);
+    printf("\t.record = %d\n", data[i].record);
+    for (j = 0; j < nFields; j++) {
+      printf("\t.value[%d].null = %d\n", j, data[i].value[j].null);
+      if (!data[i].value[j].null) {
+	switch(fldType[j]) {
+	case FIDType:
+	case IntegerType:
+	case LogicalType:
+	  printf("\t.value[%d].u.i = %d\n", j, data[i].value[j].u.i);
+	  break;
+	case DoubleType:
+	case SHPType:
+	  printf("\t.value[%d].u.d = %f\n", j, data[i].value[j].u.d);
+	  break;
+	case StringType:
+	  printf("\t.value[%d].u.s = %s\n", j, data[i].value[j].u.s);
+	  break;
+	}
+      }
+    }
+    puts("}");
+  }
+}
+#endif
+
+static struct DataStruct * build_index (SHPHandle shp, DBFHandle dbf) {
+  struct DataStruct *data;
+  SHPObject  *feat;
+  int i;
+  int j;
+
+  /* make array */
+  data = malloc (sizeof *data * nShapes);
+  if (!data) {
+    fputs("malloc failed!\n", stderr);
+    exit(EXIT_FAILURE);
+  }
+
+  /* populate array */
+  for (i = 0; i < nShapes; i++) {
+    data[i].value = malloc(sizeof data[0].value[0] * nFields);
+    if (0 == data[i].value) {
+      fputs("malloc failed!\n", stderr);
+      exit(EXIT_FAILURE);
+    }
+    data[i].record = i;
+    for (j = 0; j < nFields; j++) {
+      data[i].value[j].null = 0;
+      switch (fldType[j]) {
+      case FIDType:
+	data[i].value[j].u.i = i;
+	break;
+      case SHPType:
+	feat = SHPReadObject(shp, i);
+	switch (feat->nSHPType) {
+	case SHPT_NULL:
+	  fprintf(stderr, "Shape %d is a null feature!\n", i);
+	  data[i].value[j].null = 1;
+	  break;
+	case SHPT_POINT:
+	case SHPT_POINTZ:
+	case SHPT_POINTM:
+	case SHPT_MULTIPOINT:
+	case SHPT_MULTIPOINTZ:
+	case SHPT_MULTIPOINTM:
+	case SHPT_MULTIPATCH:
+	  /* Y-sort bounds */
+	  data[i].value[j].u.d = feat->dfYMax;
+	  break;
+	case SHPT_ARC:
+	case SHPT_ARCZ:
+	case SHPT_ARCM:
+	  data[i].value[j].u.d = shp_length(feat);
+	  break;
+	case SHPT_POLYGON:
+	case SHPT_POLYGONZ:
+	case SHPT_POLYGONM:
+	  data[i].value[j].u.d = shp_area(feat);
+	  break;
+	default:
+	  fputs("Can't sort on Shapefile feature type!\n", stderr);
+	  exit(EXIT_FAILURE);
+	}
+	SHPDestroyObject(feat);
+	break;
+      case FTString:
+	data[i].value[j].null = DBFIsAttributeNULL(dbf, i, fldIdx[j]);
+	if (!data[i].value[j].null) {
+	  data[i].value[j].u.s = dupstr(DBFReadStringAttribute(dbf, i, fldIdx[j]));
+	}
+	break;
+      case FTInteger:
+      case FTLogical:
+	data[i].value[j].null = DBFIsAttributeNULL(dbf, i, fldIdx[j]);
+	if (!data[i].value[j].null) {
+	  data[i].value[j].u.i  = DBFReadIntegerAttribute(dbf, i, fldIdx[j]);
+	}
+	break;
+      case FTDouble:
+	data[i].value[j].null = DBFIsAttributeNULL(dbf, i, fldIdx[j]);
+	if (!data[i].value[j].null) {
+	  data[i].value[j].u.d = DBFReadDoubleAttribute(dbf, i, fldIdx[j]);	
+	}
+	break;
+      }
+    }
+  }
+  
+#ifdef DEBUG
+  PrintDataStruct(data);
+  fputs("build_index: sorting array\n", stdout);
+#endif
+
+  qsort (data, nShapes, sizeof data[0], compare);
+
+#ifdef DEBUG
+  PrintDataStruct(data);
+  fputs("build_index: returning array\n", stdout);
+#endif
+
+  return data;
+}
+
+static int compare(const void *A, const void *B) {
+  const struct DataStruct *a = A;
+  const struct DataStruct *b = B;
+  int i;
+  int result = 0;
+
+  for (i = 0; i < nFields; i++) {
+    if (a->value[i].null && b->value[i].null) {
+      continue;
+    }
+    if (a->value[i].null && !b->value[i].null) {
+      return (fldOrder[i]) ? 1 : -1;
+    }
+    if (!a->value[i].null && b->value[i].null) {
+      return (fldOrder[i]) ? -1 : 1;
+    }
+    switch (fldType[i]) {
+    case FIDType:
+    case IntegerType:
+    case LogicalType:
+      if (a->value[i].u.i < b->value[i].u.i) {
+	return (fldOrder[i]) ? -1 : 1;
+      }
+      if (a->value[i].u.i > b->value[i].u.i) {
+	return (fldOrder[i]) ? 1 : -1;
+      }
+      break;
+    case DoubleType:
+    case SHPType:
+      if (a->value[i].u.d < b->value[i].u.d) {
+	return (fldOrder[i]) ? -1 : 1;
+      }
+      if (a->value[i].u.d > b->value[i].u.d) {
+	return (fldOrder[i]) ? 1 : -1;
+      }
+      break;      
+    case StringType:
+      result = strcmp(a->value[i].u.s, b->value[i].u.s);
+      if (result) {
+	return (fldOrder[i]) ? result : -result;
+      }
+      break;
+    default:
+      fprintf(stderr, "compare: Program Error! Unhandled field type! fldType[%d] = %d\n", i, fldType[i]);
+      break;
+    }
+  }
+  return 0;
+}
+
+static double area2d_polygon (int n, double *x, double *y) {
+  double area = 0;
+  int i;
+  for (i = 1; i < n; i++) {
+    area += (x[i-1] + x[i]) * (y[i] - y[i-1]);
+  }
+  return area / 2.0;
+}
+
+static double shp_area (SHPObject *feat) {
+  double area = 0.0;
+  if (feat->nParts == 0) {
+    area = area2d_polygon (feat->nVertices, feat->padfX, feat->padfY);
+  }
+  else {
+    int part, n;
+    for (part = 0; part < feat->nParts; part++) {
+      if (part < feat->nParts - 1) {
+	n = feat->panPartStart[part+1] - feat->panPartStart[part];
+      }
+      else {
+	n = feat->nVertices - feat->panPartStart[part];
+      }
+      area += area2d_polygon (n, &(feat->padfX[feat->panPartStart[part]]),
+			      &(feat->padfY[feat->panPartStart[part]]));
+    }
+  }
+  /* our area function computes in opposite direction */
+  return -area;
+}
+
+static double length2d_polyline (int n, double *x, double *y) {
+  double length = 0.0;
+  int i;
+  for (i = 1; i < n; i++) {
+    length += sqrt((x[i] - x[i-1])*(x[i] - x[i-1]) 
+		   +
+		   (y[i] - y[i-1])*(y[i] - y[i-1]));
+  }
+  return length;
+}
+
+static double shp_length (SHPObject *feat) {
+  double length = 0.0;
+  if (feat->nParts == 0) {
+    length = length2d_polyline(feat->nVertices, feat->padfX, feat->padfY);
+  }
+  else {
+    int part, n;
+    for (part = 0; part < feat->nParts; part++) {
+      if (part < feat->nParts - 1) {
+	n = feat->panPartStart[part+1] - feat->panPartStart[part];
+      }
+      else {
+	n = feat->nVertices - feat->panPartStart[part];
+      }
+      length += length2d_polyline (n, 
+				   &(feat->padfX[feat->panPartStart[part]]),
+				   &(feat->padfY[feat->panPartStart[part]]));
+    }
+  }
+  return length;
+}
+
diff --git a/contrib/shpsort.txt b/contrib/shpsort.txt
new file mode 100644
index 0000000..7e40348
--- /dev/null
+++ b/contrib/shpsort.txt
@@ -0,0 +1,44 @@
+============================= ABOUT =========================================== 
+
+The program "shpsort" is a standalone program for sorting shapefiles
+on one or more fields (including the pseudofield "SHAPE") and outputing
+the results.  People may find it useful for forcing drawing order.
+
+============================= AUTHOR ==========================================
+
+Eric G. Miller
+California Department of Fish and Game
+2004-06-30
+
+============================= USAGE ===========================================
+
+shpsort <INFILE> <OUTFILE> <SORT_FIELD;SORT_FIELD...> {SORT_ORDER;SORT_ORDER...}
+
+============================= DETAILS =========================================
+
+INFILE		The input shapefile
+
+OUTFILE		The output shapefile
+
+SORT_FIELD	Any attribute field of the shapefile, including "SHAPE"
+
+SORT_ORDER	Specify "ASCENDING" or "DESCENDING" for each SORT_FIELD.
+		This field is optional, and is assumed to be ASCENDING
+		unless the exact word "DESCENDING" is specified (case
+		matters).
+
+	When sorting on the "SHAPE" the records are sorted as follows:
+
+	*  Null shapes are treated as any other null field and will
+	   sort to the top in ASCENDING mode.  A warning is issued
+	   for each null shape encountered.
+	*  POINT, POINTM, POINTZ, MULTIPOINT, MULTIPOINTM, MULTIPOINTZ
+	   and MULTIPATCH are all sorted by the maximum "Y" value of
+	   their envelopes (not particularly useful).
+	*  POLYLINE, POLYLINEZ and POLYLINEM are sorted by total 2d 
+	   shape length.
+	*  POLYGON, POLYGONZ and POLYGONM are sorted by the 2d shape 
+	   area. Shapes are assumed to be in canonical ordering, so that
+	   the area of interior rings (if any) is subtracted from the
+	   area of exterior rings.
+
diff --git a/contrib/shpwkb.c b/contrib/shpwkb.c
index b11fb80..7c2725b 100644
--- a/contrib/shpwkb.c
+++ b/contrib/shpwkb.c
@@ -26,7 +26,7 @@
  *
  *
  * $Log: shpwkb.c,v $
- * Revision 1.1  1999/05/26 02:29:36  candrsn
+ * Revision 1.1  1999-05-26 02:29:36  candrsn
  * OGis Well Known Binary test program (output only)
  *
  *
diff --git a/contrib/tests/shpproj.sh b/contrib/tests/shpproj.sh
index 3520929..4996791 100755
--- a/contrib/tests/shpproj.sh
+++ b/contrib/tests/shpproj.sh
@@ -11,7 +11,7 @@ shpadd test -84.01681518              34.67275985
 shpadd test -84.15596023              34.64862437
 shpadd test -83.61951463              34.54927047
 
-dbfcreate test -s 30 fd
+dbfcreate test -s fd 30
 dbfadd test "1"
 dbfadd test "2"
 dbfadd test "3"
@@ -35,4 +35,4 @@ fi
 rm test*
 
 
-cd ..
\ No newline at end of file
+cd ..
diff --git a/dbfadd.c b/dbfadd.c
index f978208..3d323ec 100644
--- a/dbfadd.c
+++ b/dbfadd.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: dbfadd.c,v 1.7 2002/01/15 14:36:07 warmerda Exp $
+ * $Id: dbfadd.c,v 1.9 2004-09-26 20:09:35 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Sample application for adding a record to an existing .dbf file.
@@ -34,6 +34,12 @@
  ******************************************************************************
  *
  * $Log: dbfadd.c,v $
+ * Revision 1.9  2004-09-26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
+ * Revision 1.8  2004/01/09 16:39:49  fwarmerdam
+ * include standard include files
+ *
  * Revision 1.7  2002/01/15 14:36:07  warmerda
  * updated email address
  *
@@ -54,13 +60,14 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: dbfadd.c,v 1.7 2002/01/15 14:36:07 warmerda Exp $";
-
-#include "shapefil.h"
+#include <string.h>
 #include <math.h>
 #include <stdlib.h>
 
+#include "shapefil.h"
+
+SHP_CVSID("$Id: dbfadd.c,v 1.9 2004-09-26 20:09:35 fwarmerdam Exp $")
+
 int main( int argc, char ** argv )
 
 {
diff --git a/dbfcreate.c b/dbfcreate.c
index f1e22ab..eb5ddfc 100644
--- a/dbfcreate.c
+++ b/dbfcreate.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: dbfcreate.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $
+ * $Id: dbfcreate.c,v 1.7 2004-09-26 20:09:35 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Sample application for creating a new .dbf file.
@@ -34,6 +34,9 @@
  ******************************************************************************
  *
  * $Log: dbfcreate.c,v $
+ * Revision 1.7  2004-09-26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
  * Revision 1.6  2002/01/15 14:36:07  warmerda
  * updated email address
  *
@@ -51,13 +54,12 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: dbfcreate.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $";
-
 #include <stdlib.h>
 #include <string.h>
 #include "shapefil.h"
 
+SHP_CVSID("$Id: dbfcreate.c,v 1.7 2004-09-26 20:09:35 fwarmerdam Exp $")
+
 int main( int argc, char ** argv )
 
 {
diff --git a/dbfdump.c b/dbfdump.c
index 9fe44fa..8c3e65e 100644
--- a/dbfdump.c
+++ b/dbfdump.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: dbfdump.c,v 1.9 2002/01/15 14:36:07 warmerda Exp $
+ * $Id: dbfdump.c,v 1.12 2006-06-17 00:15:08 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Sample application for dumping .dbf files to the terminal.
@@ -34,6 +34,15 @@
  ******************************************************************************
  *
  * $Log: dbfdump.c,v $
+ * Revision 1.12  2006-06-17 00:15:08  fwarmerdam
+ * Free panWidth for better memory testing.
+ *
+ * Revision 1.11  2006/02/15 01:11:27  fwarmerdam
+ * added reporting of native type
+ *
+ * Revision 1.10  2004/09/26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
  * Revision 1.9  2002/01/15 14:36:07  warmerda
  * updated email address
  *
@@ -60,13 +69,12 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: dbfdump.c,v 1.9 2002/01/15 14:36:07 warmerda Exp $";
-
 #include <stdlib.h>
 #include <string.h>
 #include "shapefil.h"
 
+SHP_CVSID("$Id: dbfdump.c,v 1.12 2006-06-17 00:15:08 fwarmerdam Exp $")
+
 int main( int argc, char ** argv )
 
 {
@@ -134,6 +142,9 @@ int main( int argc, char ** argv )
         {
             DBFFieldType	eType;
             const char	 	*pszTypeName;
+            char chNativeType;
+
+            chNativeType = DBFGetNativeFieldType( hDBF, i );
 
             eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
             if( eType == FTString )
@@ -145,8 +156,8 @@ int main( int argc, char ** argv )
             else if( eType == FTInvalid )
                 pszTypeName = "Invalid";
 
-            printf( "Field %d: Type=%s, Title=`%s', Width=%d, Decimals=%d\n",
-                    i, pszTypeName, szTitle, nWidth, nDecimals );
+            printf( "Field %d: Type=%c/%s, Title=`%s', Width=%d, Decimals=%d\n",
+                    i, chNativeType, pszTypeName, szTitle, nWidth, nDecimals );
         }
     }
 
@@ -162,7 +173,7 @@ int main( int argc, char ** argv )
 	DBFFieldType	eType;
 
 	eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
-	if( strlen(szTitle) > nWidth )
+	if( (int) strlen(szTitle) > nWidth )
 	    panWidth[i] = strlen(szTitle);
 	else
 	    panWidth[i] = nWidth;
@@ -266,6 +277,7 @@ int main( int argc, char ** argv )
     }
 
     DBFClose( hDBF );
+    free( panWidth );
 
     return( 0 );
 }
diff --git a/dbfopen.c b/dbfopen.c
index 43b25ac..fbe7b06 100644
--- a/dbfopen.c
+++ b/dbfopen.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: dbfopen.c,v 1.48 2003/03/10 14:51:27 warmerda Exp $
+ * $Id: dbfopen.c,v 1.89 2011-07-24 05:59:25 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
@@ -34,157 +34,128 @@
  ******************************************************************************
  *
  * $Log: dbfopen.c,v $
- * Revision 1.48  2003/03/10 14:51:27  warmerda
- * DBFWrite* calls now return FALSE if they have to truncate
+ * Revision 1.89  2011-07-24 05:59:25  fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
  *
- * Revision 1.47  2002/11/20 03:32:22  warmerda
- * Ensure field name in DBFGetFieldIndex() is properly terminated.
+ * Revision 1.88  2011-05-13 17:35:17  fwarmerdam
+ * added DBFReorderFields() and DBFAlterFields() functions (from Even)
  *
- * Revision 1.46  2002/10/09 13:10:21  warmerda
- * Added check that width is positive.
+ * Revision 1.87  2011-05-07 22:41:02  fwarmerdam
+ * ensure pending record is flushed when adding a native field (GDAL #4073)
  *
- * Revision 1.45  2002/09/29 00:00:08  warmerda
- * added FTLogical and logical attribute read/write calls
+ * Revision 1.86  2011-04-17 15:15:29  fwarmerdam
+ * Removed unused variable.
  *
- * Revision 1.44  2002/05/07 13:46:11  warmerda
- * Added DBFWriteAttributeDirectly().
+ * Revision 1.85  2010-12-06 16:09:34  fwarmerdam
+ * fix buffer read overrun fetching code page (bug 2276)
  *
- * Revision 1.43  2002/02/13 19:39:21  warmerda
- * Fix casting issues in DBFCloneEmpty().
+ * Revision 1.84  2009-10-29 19:59:48  fwarmerdam
+ * avoid crash on truncated header (gdal #3093)
  *
- * Revision 1.42  2002/01/15 14:36:07  warmerda
- * updated email address
+ * Revision 1.83  2008/11/12 14:28:15  fwarmerdam
+ * DBFCreateField() now works on files with records
  *
- * Revision 1.41  2002/01/15 14:31:49  warmerda
- * compute rather than copying nHeaderLength in DBFCloneEmpty()
+ * Revision 1.82  2008/11/11 17:47:09  fwarmerdam
+ * added DBFDeleteField() function
  *
- * Revision 1.40  2002/01/09 04:32:35  warmerda
- * fixed to read correct amount of header
+ * Revision 1.81  2008/01/03 17:48:13  bram
+ * in DBFCreate, use default code page LDID/87 (= 0x57, ANSI)
+ * instead of LDID/3.  This seems to be the same as what ESRI
+ * would be doing by default.
  *
- * Revision 1.39  2001/12/11 22:41:03  warmerda
- * improve io related error checking when reading header
+ * Revision 1.80  2007/12/30 14:36:39  fwarmerdam
+ * avoid syntax issue with last comment.
  *
- * Revision 1.38  2001/11/28 16:07:31  warmerda
- * Cleanup to avoid compiler warnings as suggested by Richard Hash.
+ * Revision 1.79  2007/12/30 14:35:48  fwarmerdam
+ * Avoid char* / unsigned char* warnings.
  *
- * Revision 1.37  2001/07/04 05:18:09  warmerda
- * do last fix properly
+ * Revision 1.78  2007/12/18 18:28:07  bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
  *
- * Revision 1.36  2001/07/04 05:16:09  warmerda
- * fixed fieldname comparison in DBFGetFieldIndex
+ * Revision 1.77  2007/12/15 20:25:21  bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function.  This is 
+ * either the number from the LDID header field ("LDID/<number>") or as the 
+ * content of an accompanying .CPG file.  When creating a DBF file, the code can
+ * be set using DBFCreateEx.
  *
- * Revision 1.35  2001/06/22 02:10:06  warmerda
- * fixed NULL shape support with help from Jim Matthews
+ * Revision 1.76  2007/12/12 22:21:32  bram
+ * DBFClose: check for NULL psDBF handle before trying to close it.
  *
- * Revision 1.33  2001/05/31 19:20:13  warmerda
- * added DBFGetFieldIndex()
+ * Revision 1.75  2007/12/06 13:58:19  fwarmerdam
+ * make sure file offset calculations are done in as SAOffset
  *
- * Revision 1.32  2001/05/31 18:15:40  warmerda
- * Added support for NULL fields in DBF files
+ * Revision 1.74  2007/12/06 07:00:25  fwarmerdam
+ * dbfopen now using SAHooks for fileio
  *
- * Revision 1.31  2001/05/23 13:36:52  warmerda
- * added use of SHPAPI_CALL
+ * Revision 1.73  2007/09/03 19:48:11  fwarmerdam
+ * move DBFReadAttribute() static dDoubleField into dbfinfo
  *
- * Revision 1.30  2000/12/05 14:43:38  warmerda
- * DBReadAttribute() white space trimming bug fix
+ * Revision 1.72  2007/09/03 19:34:06  fwarmerdam
+ * Avoid use of static tuple buffer in DBFReadTuple()
  *
- * Revision 1.29  2000/10/05 14:36:44  warmerda
- * fix bug with writing very wide numeric fields
+ * Revision 1.71  2006/06/22 14:37:18  fwarmerdam
+ * avoid memory leak if dbfopen fread fails
  *
- * Revision 1.28  2000/09/25 14:18:07  warmerda
- * Added some casts of strlen() return result to fix warnings on some
- * systems, as submitted by Daniel.
+ * Revision 1.70  2006/06/17 17:47:05  fwarmerdam
+ * use calloc() for dbfinfo in DBFCreate
  *
- * Revision 1.27  2000/09/25 14:15:51  warmerda
- * added DBFGetNativeFieldType()
+ * Revision 1.69  2006/06/17 15:34:32  fwarmerdam
+ * disallow creating fields wider than 255
  *
- * Revision 1.26  2000/07/07 13:39:45  warmerda
- * removed unused variables, and added system include files
+ * Revision 1.68  2006/06/17 15:12:40  fwarmerdam
+ * Fixed C++ style comments.
  *
- * Revision 1.25  2000/05/29 18:19:13  warmerda
- * avoid use of uchar, and adding casting fix
+ * Revision 1.67  2006/06/17 00:24:53  fwarmerdam
+ * Don't treat non-zero decimals values as high order byte for length
+ * for strings.  It causes serious corruption for some files.
+ * http://bugzilla.remotesensing.org/show_bug.cgi?id=1202
  *
- * Revision 1.24  2000/05/23 13:38:27  warmerda
- * Added error checks on return results of fread() and fseek().
+ * Revision 1.66  2006/03/29 18:26:20  fwarmerdam
+ * fixed bug with size of pachfieldtype in dbfcloneempty
  *
- * Revision 1.23  2000/05/23 13:25:49  warmerda
- * Avoid crashing if field or record are out of range in dbfread*attribute().
+ * Revision 1.65  2006/02/15 01:14:30  fwarmerdam
+ * added DBFAddNativeFieldType
  *
- * Revision 1.22  1999/12/15 13:47:24  warmerda
- * Added stdlib.h to ensure that atof() is prototyped.
+ * Revision 1.64  2006/02/09 00:29:04  fwarmerdam
+ * Changed to put spaces into string fields that are NULL as
+ * per http://bugzilla.maptools.org/show_bug.cgi?id=316.
  *
- * Revision 1.21  1999/12/13 17:25:46  warmerda
- * Added support for upper case .DBF extention.
+ * Revision 1.63  2006/01/25 15:35:43  fwarmerdam
+ * check success on DBFFlushRecord
  *
- * Revision 1.20  1999/11/30 16:32:11  warmerda
- * Use atof() instead of sscanf().
+ * Revision 1.62  2006/01/10 16:28:03  fwarmerdam
+ * Fixed typo in CPLError.
  *
- * Revision 1.19  1999/11/05 14:12:04  warmerda
- * updated license terms
+ * Revision 1.61  2006/01/10 16:26:29  fwarmerdam
+ * Push loading record buffer into DBFLoadRecord.
+ * Implement CPL error reporting if USE_CPL defined.
  *
- * Revision 1.18  1999/07/27 00:53:28  warmerda
- * ensure that whole old field value clear on write of string
+ * Revision 1.60  2006/01/05 01:27:27  fwarmerdam
+ * added dbf deletion mark/fetch
  *
- * Revision 1.1  1999/07/05 18:58:07  warmerda
- * New
+ * Revision 1.59  2005/03/14 15:20:28  fwarmerdam
+ * Fixed last change.
  *
- * Revision 1.17  1999/06/11 19:14:12  warmerda
- * Fixed some memory leaks.
+ * Revision 1.58  2005/03/14 15:18:54  fwarmerdam
+ * Treat very wide fields with no decimals as double.  This is
+ * more than 32bit integer fields.
  *
- * Revision 1.16  1999/06/11 19:04:11  warmerda
- * Remoted some unused variables.
+ * Revision 1.57  2005/02/10 20:16:54  fwarmerdam
+ * Make the pszStringField buffer for DBFReadAttribute() static char [256]
+ * as per bug 306.
  *
- * Revision 1.15  1999/05/11 03:19:28  warmerda
- * added new Tuple api, and improved extension handling - add from candrsn
+ * Revision 1.56  2005/02/10 20:07:56  fwarmerdam
+ * Fixed bug 305 in DBFCloneEmpty() - header length problem.
  *
- * Revision 1.14  1999/05/04 15:01:48  warmerda
- * Added 'F' support.
+ * Revision 1.55  2004/09/26 20:23:46  fwarmerdam
+ * avoid warnings with rcsid and signed/unsigned stuff
  *
- * Revision 1.13  1999/03/23 17:38:59  warmerda
- * DBFAddField() now actually does return the new field number, or -1 if
- * it fails.
- *
- * Revision 1.12  1999/03/06 02:54:46  warmerda
- * Added logic to convert shapefile name to dbf filename in DBFOpen()
- * for convenience.
- *
- * Revision 1.11  1998/12/31 15:30:34  warmerda
- * Improved the interchangability of numeric and string attributes.  Add
- * white space trimming option for attributes.
- *
- * Revision 1.10  1998/12/03 16:36:44  warmerda
- * Use r+b instead of rb+ for binary access.
- *
- * Revision 1.9  1998/12/03 15:34:23  warmerda
- * Updated copyright message.
- *
- * Revision 1.8  1997/12/04 15:40:15  warmerda
- * Added newline character after field definitions.
- *
- * Revision 1.7  1997/03/06 14:02:10  warmerda
- * Ensure bUpdated is initialized.
- *
- * Revision 1.6  1996/02/12 04:54:41  warmerda
- * Ensure that DBFWriteAttribute() returns TRUE if it succeeds.
- *
- * Revision 1.5  1995/10/21  03:15:12  warmerda
- * Changed to use binary file access, and ensure that the
- * field name field is zero filled, and limited to 10 chars.
- *
- * Revision 1.4  1995/08/24  18:10:42  warmerda
- * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such
- * as on the Sun.
- *
- * Revision 1.3  1995/08/04  03:15:16  warmerda
- * Fixed up header.
- *
- * Revision 1.2  1995/08/04  03:14:43  warmerda
- * Added header.
+ * Revision 1.54  2004/09/15 16:26:10  fwarmerdam
+ * Treat all blank numeric fields as null too.
  */
 
-static char rcsid[] = 
-  "$Id: dbfopen.c,v 1.48 2003/03/10 14:51:27 warmerda Exp $";
-
 #include "shapefil.h"
 
 #include <math.h>
@@ -192,14 +163,13 @@ static char rcsid[] =
 #include <ctype.h>
 #include <string.h>
 
+SHP_CVSID("$Id: dbfopen.c,v 1.89 2011-07-24 05:59:25 fwarmerdam Exp $")
+
 #ifndef FALSE
 #  define FALSE		0
 #  define TRUE		1
 #endif
 
-static int	nStringFieldLen = 0;
-static char * pszStringField = NULL;
-
 /************************************************************************/
 /*                             SfRealloc()                              */
 /*                                                                      */
@@ -244,21 +214,29 @@ static void DBFWriteHeader(DBFHandle psDBF)
 
     abyHeader[0] = 0x03;		/* memo field? - just copying 	*/
 
-    /* date updated on close, record count preset at zero */
+    /* write out a dummy date */
+    abyHeader[1] = 95;			/* YY */
+    abyHeader[2] = 7;			/* MM */
+    abyHeader[3] = 26;			/* DD */
 
-    abyHeader[8] = psDBF->nHeaderLength % 256;
-    abyHeader[9] = psDBF->nHeaderLength / 256;
+    /* record count preset at zero */
+
+    abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
+    abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
     
-    abyHeader[10] = psDBF->nRecordLength % 256;
-    abyHeader[11] = psDBF->nRecordLength / 256;
+    abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
+    abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
+
+    abyHeader[29] = (unsigned char) (psDBF->iLanguageDriver);
 
 /* -------------------------------------------------------------------- */
 /*      Write the initial 32 byte file header, and all the field        */
 /*      descriptions.                                     		*/
 /* -------------------------------------------------------------------- */
-    fseek( psDBF->fp, 0, 0 );
-    fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
-    fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
+    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+    psDBF->sHooks.FWrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
+    psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, 
+                          psDBF->fp );
 
 /* -------------------------------------------------------------------- */
 /*      Write out the newline character if there is room for it.        */
@@ -268,7 +246,7 @@ static void DBFWriteHeader(DBFHandle psDBF)
         char	cNewline;
 
         cNewline = 0x0d;
-        fwrite( &cNewline, 1, 1, psDBF->fp );
+        psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
     }
 }
 
@@ -278,21 +256,104 @@ static void DBFWriteHeader(DBFHandle psDBF)
 /*      Write out the current record if there is one.                   */
 /************************************************************************/
 
-static void DBFFlushRecord( DBFHandle psDBF )
+static int DBFFlushRecord( DBFHandle psDBF )
 
 {
-    int		nRecordOffset;
+    SAOffset	nRecordOffset;
 
     if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
     {
 	psDBF->bCurrentRecordModified = FALSE;
 
-	nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord 
-	                                             + psDBF->nHeaderLength;
+	nRecordOffset = 
+            psDBF->nRecordLength * (SAOffset) psDBF->nCurrentRecord 
+            + psDBF->nHeaderLength;
+
+	if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0 
+            || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord, 
+                                     psDBF->nRecordLength, 
+                                     1, psDBF->fp ) != 1 )
+        {
+            char szMessage[128];
+            sprintf( szMessage, "Failure writing DBF record %d.", 
+                     psDBF->nCurrentRecord );
+            psDBF->sHooks.Error( szMessage );
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                           DBFLoadRecord()                            */
+/************************************************************************/
+
+static int DBFLoadRecord( DBFHandle psDBF, int iRecord )
+
+{
+    if( psDBF->nCurrentRecord != iRecord )
+    {
+        SAOffset nRecordOffset;
+
+	if( !DBFFlushRecord( psDBF ) )
+            return FALSE;
+
+	nRecordOffset = 
+            psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+	if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
+        {
+            char szMessage[128];
+            sprintf( szMessage, "fseek(%ld) failed on DBF file.\n",
+                     (long) nRecordOffset );
+            psDBF->sHooks.Error( szMessage );
+            return FALSE;
+        }
+
+	if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord, 
+                                 psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
+        {
+            char szMessage[128];
+            sprintf( szMessage, "fread(%d) failed on DBF file.\n",
+                     psDBF->nRecordLength );
+            psDBF->sHooks.Error( szMessage );
+            return FALSE;
+        }
 
-	fseek( psDBF->fp, nRecordOffset, 0 );
-	fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+	psDBF->nCurrentRecord = iRecord;
     }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                          DBFUpdateHeader()                           */
+/************************************************************************/
+
+void SHPAPI_CALL
+DBFUpdateHeader( DBFHandle psDBF )
+
+{
+    unsigned char		abyFileHeader[32];
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader( psDBF );
+
+    DBFFlushRecord( psDBF );
+
+    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+    psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp );
+    
+    abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
+    abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
+    abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
+    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
+    
+    psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+    psDBF->sHooks.FWrite( abyFileHeader, 32, 1, psDBF->fp );
+
+    psDBF->sHooks.FFlush( psDBF->fp );
 }
 
 /************************************************************************/
@@ -305,10 +366,29 @@ DBFHandle SHPAPI_CALL
 DBFOpen( const char * pszFilename, const char * pszAccess )
 
 {
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return DBFOpenLL( pszFilename, pszAccess, &sHooks );
+}
+
+/************************************************************************/
+/*                              DBFOpen()                               */
+/*                                                                      */
+/*      Open a .dbf file.                                               */
+/************************************************************************/
+   
+DBFHandle SHPAPI_CALL
+DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
+
+{
     DBFHandle		psDBF;
-    unsigned char		*pabyBuf;
-    int			nFields, nHeadLen, nRecLen, iField, i;
+    SAFile		pfCPG;
+    unsigned char	*pabyBuf;
+    int			nFields, nHeadLen, iField, i;
     char		*pszBasename, *pszFullname;
+    int                 nBufSize = 500;
 
 /* -------------------------------------------------------------------- */
 /*      We only allow the access strings "rb" and "r+".                  */
@@ -342,20 +422,30 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
     sprintf( pszFullname, "%s.dbf", pszBasename );
         
     psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
-    psDBF->fp = fopen( pszFullname, pszAccess );
+    psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
+    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
 
     if( psDBF->fp == NULL )
     {
         sprintf( pszFullname, "%s.DBF", pszBasename );
-        psDBF->fp = fopen(pszFullname, pszAccess );
+        psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
     }
-    
+
+    sprintf( pszFullname, "%s.cpg", pszBasename );
+    pfCPG = psHooks->FOpen( pszFullname, "r" );
+    if( pfCPG == NULL )
+    {
+        sprintf( pszFullname, "%s.CPG", pszBasename );
+        pfCPG = psHooks->FOpen( pszFullname, "r" );
+    }
+
     free( pszBasename );
     free( pszFullname );
     
     if( psDBF->fp == NULL )
     {
         free( psDBF );
+        if( pfCPG ) psHooks->FClose( pfCPG );
         return( NULL );
     }
 
@@ -366,10 +456,11 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
 /* -------------------------------------------------------------------- */
 /*  Read Table Header info                                              */
 /* -------------------------------------------------------------------- */
-    pabyBuf = (unsigned char *) malloc(500);
-    if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
+    pabyBuf = (unsigned char *) malloc(nBufSize);
+    if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
     {
-        fclose( psDBF->fp );
+        psDBF->sHooks.FClose( psDBF->fp );
+        if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
         free( pabyBuf );
         free( psDBF );
         return NULL;
@@ -379,11 +470,47 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
      pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
 
     psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
-    psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
-    
+    psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11]*256;
+    psDBF->iLanguageDriver = pabyBuf[29];
+
+    if (nHeadLen < 32)
+    {
+        psDBF->sHooks.FClose( psDBF->fp );
+        if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
+        free( pabyBuf );
+        free( psDBF );
+        return NULL;
+    }
+
     psDBF->nFields = nFields = (nHeadLen - 32) / 32;
 
-    psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
+    psDBF->pszCurrentRecord = (char *) malloc(psDBF->nRecordLength);
+
+/* -------------------------------------------------------------------- */
+/*  Figure out the code page from the LDID and CPG                      */
+/* -------------------------------------------------------------------- */
+
+    psDBF->pszCodePage = NULL;
+    if( pfCPG )
+    {
+        size_t n;
+        memset( pabyBuf, 0, nBufSize);
+        psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
+        n = strcspn( (char *) pabyBuf, "\n\r" );
+        if( n > 0 )
+        {
+            pabyBuf[n] = '\0';
+            psDBF->pszCodePage = (char *) malloc(n + 1);
+            memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
+        }
+		psDBF->sHooks.FClose( pfCPG );
+    }
+    if( psDBF->pszCodePage == NULL && pabyBuf[29] != 0 )
+    {
+        sprintf( (char *) pabyBuf, "LDID/%d", psDBF->iLanguageDriver );
+        psDBF->pszCodePage = (char *) malloc(strlen((char*)pabyBuf) + 1);
+        strcpy( psDBF->pszCodePage, (char *) pabyBuf );
+    }
 
 /* -------------------------------------------------------------------- */
 /*  Read in Field Definitions                                           */
@@ -392,11 +519,12 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
     pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
     psDBF->pszHeader = (char *) pabyBuf;
 
-    fseek( psDBF->fp, 32, 0 );
-    if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
+    psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
+    if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
     {
-        fclose( psDBF->fp );
+        psDBF->sHooks.FClose( psDBF->fp );
         free( pabyBuf );
+        free( psDBF->pszCurrentRecord );
         free( psDBF );
         return NULL;
     }
@@ -419,8 +547,17 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
 	}
 	else
 	{
+	    psDBF->panFieldSize[iField] = pabyFInfo[16];
+	    psDBF->panFieldDecimals[iField] = 0;
+
+/*
+** The following seemed to be used sometimes to handle files with long
+** string fields, but in other cases (such as bug 1202) the decimals field
+** just seems to indicate some sort of preferred formatting, not very
+** wide fields.  So I have disabled this code.  FrankW.
 	    psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
 	    psDBF->panFieldDecimals[iField] = 0;
+*/
 	}
 
 	psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
@@ -441,6 +578,9 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
 void SHPAPI_CALL
 DBFClose(DBFHandle psDBF)
 {
+    if( psDBF == NULL )
+        return;
+
 /* -------------------------------------------------------------------- */
 /*      Write out header if not already written.                        */
 /* -------------------------------------------------------------------- */
@@ -454,29 +594,12 @@ DBFClose(DBFHandle psDBF)
 /*	write access.                					*/
 /* -------------------------------------------------------------------- */
     if( psDBF->bUpdated )
-    {
-	unsigned char		abyFileHeader[32];
-
-	fseek( psDBF->fp, 0, 0 );
-	fread( abyFileHeader, 32, 1, psDBF->fp );
-
-	abyFileHeader[1] = 95;			/* YY */
-	abyFileHeader[2] = 7;			/* MM */
-	abyFileHeader[3] = 26;			/* DD */
-
-	abyFileHeader[4] = psDBF->nRecords % 256;
-	abyFileHeader[5] = (psDBF->nRecords/256) % 256;
-	abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256;
-	abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256;
-
-	fseek( psDBF->fp, 0, 0 );
-	fwrite( abyFileHeader, 32, 1, psDBF->fp );
-    }
+        DBFUpdateHeader( psDBF );
 
 /* -------------------------------------------------------------------- */
 /*      Close, and free resources.                                      */
 /* -------------------------------------------------------------------- */
-    fclose( psDBF->fp );
+    psDBF->sHooks.FClose( psDBF->fp );
 
     if( psDBF->panFieldOffset != NULL )
     {
@@ -486,17 +609,44 @@ DBFClose(DBFHandle psDBF)
         free( psDBF->pachFieldType );
     }
 
+    if( psDBF->pszWorkField != NULL )
+        free( psDBF->pszWorkField );
+
     free( psDBF->pszHeader );
     free( psDBF->pszCurrentRecord );
+    free( psDBF->pszCodePage );
 
     free( psDBF );
+}
 
-    if( pszStringField != NULL )
-    {
-        free( pszStringField );
-        pszStringField = NULL;
-        nStringFieldLen = 0;
-    }
+/************************************************************************/
+/*                             DBFCreate()                              */
+/*                                                                      */
+/* Create a new .dbf file with default code page LDID/87 (0x57)         */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreate( const char * pszFilename )
+
+{
+    return DBFCreateEx( pszFilename, "LDID/87" ); // 0x57
+}
+
+/************************************************************************/
+/*                            DBFCreateEx()                             */
+/*                                                                      */
+/*      Create a new .dbf file.                                         */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreateEx( const char * pszFilename, const char* pszCodePage )
+
+{
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return DBFCreateLL( pszFilename, pszCodePage , &sHooks );
 }
 
 /************************************************************************/
@@ -506,13 +656,14 @@ DBFClose(DBFHandle psDBF)
 /************************************************************************/
 
 DBFHandle SHPAPI_CALL
-DBFCreate( const char * pszFilename )
+DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHooks )
 
 {
     DBFHandle	psDBF;
-    FILE	*fp;
+    SAFile	fp;
     char	*pszFullname, *pszBasename;
-    int		i;
+    int		i, ldid = -1;
+    char chZero = '\0';
 
 /* -------------------------------------------------------------------- */
 /*	Compute the base (layer) name.  If there is any extension	*/
@@ -530,29 +681,52 @@ DBFCreate( const char * pszFilename )
 
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
     sprintf( pszFullname, "%s.dbf", pszBasename );
-    free( pszBasename );
 
 /* -------------------------------------------------------------------- */
 /*      Create the file.                                                */
 /* -------------------------------------------------------------------- */
-    fp = fopen( pszFullname, "wb" );
+    fp = psHooks->FOpen( pszFullname, "wb" );
     if( fp == NULL )
         return( NULL );
+    
+    psHooks->FWrite( &chZero, 1, 1, fp );
+    psHooks->FClose( fp );
 
-    fputc( 0, fp );
-    fclose( fp );
-
-    fp = fopen( pszFullname, "rb+" );
+    fp = psHooks->FOpen( pszFullname, "rb+" );
     if( fp == NULL )
         return( NULL );
 
+
+    sprintf( pszFullname, "%s.cpg", pszBasename );
+    if( pszCodePage != NULL )
+    {
+        if( strncmp( pszCodePage, "LDID/", 5 ) == 0 )
+        {
+            ldid = atoi( pszCodePage + 5 );
+            if( ldid > 255 )
+                ldid = -1; // don't use 0 to indicate out of range as LDID/0 is a valid one
+        }
+        if( ldid < 0 )
+        {
+            SAFile fpCPG = psHooks->FOpen( pszFullname, "w" );
+            psHooks->FWrite( (char*) pszCodePage, strlen(pszCodePage), 1, fpCPG );
+            psHooks->FClose( fpCPG );
+        }
+    }
+    if( pszCodePage == NULL || ldid >= 0 )
+    {
+        psHooks->Remove( pszFullname );
+    }
+
+    free( pszBasename );
     free( pszFullname );
 
 /* -------------------------------------------------------------------- */
 /*	Create the info structure.					*/
 /* -------------------------------------------------------------------- */
-    psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
+    psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo));
 
+    memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
     psDBF->fp = fp;
     psDBF->nRecords = 0;
     psDBF->nFields = 0;
@@ -571,14 +745,21 @@ DBFCreate( const char * pszFilename )
 
     psDBF->bNoHeader = TRUE;
 
+    psDBF->iLanguageDriver = ldid > 0 ? ldid : 0;
+    psDBF->pszCodePage = NULL;
+    if( pszCodePage )
+    {
+        psDBF->pszCodePage = (char * ) malloc( strlen(pszCodePage) + 1 );
+        strcpy( psDBF->pszCodePage, pszCodePage );
+    }
+
     return( psDBF );
 }
 
 /************************************************************************/
 /*                            DBFAddField()                             */
 /*                                                                      */
-/*      Add a field to a newly created .dbf file before any records     */
-/*      are written.                                                    */
+/*      Add a field to a newly created .dbf or to an existing one       */
 /************************************************************************/
 
 int SHPAPI_CALL
@@ -586,24 +767,74 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
             DBFFieldType eType, int nWidth, int nDecimals )
 
 {
+    char chNativeType = 'C';
+
+    if( eType == FTLogical )
+        chNativeType = 'L';
+    else if( eType == FTString )
+        chNativeType = 'C';
+    else
+        chNativeType = 'N';
+
+    return DBFAddNativeFieldType( psDBF, pszFieldName, chNativeType, 
+                                  nWidth, nDecimals );
+}
+
+/************************************************************************/
+/*                        DBFGetNullCharacter()                         */
+/************************************************************************/
+
+static char DBFGetNullCharacter(char chType)
+{
+    switch (chType)
+    {
+      case 'N':
+      case 'F':
+        return '*';
+      case 'D':
+        return '0';
+      case 'L':
+       return '?';
+      default:
+       return ' ';
+    }
+}
+
+/************************************************************************/
+/*                            DBFAddField()                             */
+/*                                                                      */
+/*      Add a field to a newly created .dbf file before any records     */
+/*      are written.                                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, 
+                      char chType, int nWidth, int nDecimals )
+
+{
     char	*pszFInfo;
     int		i;
+    int         nOldRecordLength, nOldHeaderLength;
+    char        *pszRecord;
+    char        chFieldFill;
+    SAOffset    nRecordOffset;
+
+    /* make sure that everything is written in .dbf */
+    if( !DBFFlushRecord( psDBF ) )
+        return -1;
 
 /* -------------------------------------------------------------------- */
 /*      Do some checking to ensure we can add records to this file.     */
 /* -------------------------------------------------------------------- */
-    if( psDBF->nRecords > 0 )
-        return( -1 );
-
-    if( !psDBF->bNoHeader )
-        return( -1 );
-
-    if( eType != FTDouble && nDecimals != 0 )
-        return( -1 );
-
     if( nWidth < 1 )
         return -1;
 
+    if( nWidth > 255 )
+        nWidth = 255;
+
+    nOldRecordLength = psDBF->nRecordLength;
+    nOldHeaderLength = psDBF->nHeaderLength;
+
 /* -------------------------------------------------------------------- */
 /*      SfRealloc all the arrays larger to hold the additional field      */
 /*      information.                                                    */
@@ -611,16 +842,16 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
     psDBF->nFields++;
 
     psDBF->panFieldOffset = (int *) 
-      SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+        SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
 
     psDBF->panFieldSize = (int *) 
-      SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+        SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
 
     psDBF->panFieldDecimals = (int *) 
-      SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+        SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
 
     psDBF->pachFieldType = (char *) 
-      SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+        SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
 
 /* -------------------------------------------------------------------- */
 /*      Assign the new field information fields.                        */
@@ -629,13 +860,7 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
     psDBF->nRecordLength += nWidth;
     psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
     psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
-
-    if( eType == FTLogical )
-        psDBF->pachFieldType[psDBF->nFields-1] = 'L';
-    else if( eType == FTString )
-        psDBF->pachFieldType[psDBF->nFields-1] = 'C';
-    else
-        psDBF->pachFieldType[psDBF->nFields-1] = 'N';
+    psDBF->pachFieldType[psDBF->nFields-1] = chType;
 
 /* -------------------------------------------------------------------- */
 /*      Extend the required header information.                         */
@@ -657,22 +882,63 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
 
     pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
 
-    if( eType == FTString )
+    if( chType == 'C' )
     {
-        pszFInfo[16] = nWidth % 256;
-        pszFInfo[17] = nWidth / 256;
+        pszFInfo[16] = (unsigned char) (nWidth % 256);
+        pszFInfo[17] = (unsigned char) (nWidth / 256);
     }
     else
     {
-        pszFInfo[16] = nWidth;
-        pszFInfo[17] = nDecimals;
+        pszFInfo[16] = (unsigned char) nWidth;
+        pszFInfo[17] = (unsigned char) nDecimals;
     }
     
 /* -------------------------------------------------------------------- */
 /*      Make the current record buffer appropriately larger.            */
 /* -------------------------------------------------------------------- */
     psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
-					       psDBF->nRecordLength);
+                                                 psDBF->nRecordLength);
+
+    /* we're done if dealing with new .dbf */
+    if( psDBF->bNoHeader )
+        return( psDBF->nFields - 1 );
+
+/* -------------------------------------------------------------------- */
+/*      For existing .dbf file, shift records                           */
+/* -------------------------------------------------------------------- */
+
+    /* alloc record */
+    pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+
+    chFieldFill = DBFGetNullCharacter(chType);
+
+    for (i = psDBF->nRecords-1; i >= 0; --i)
+    {
+        nRecordOffset = nOldRecordLength * (SAOffset) i + nOldHeaderLength;
+
+        /* load record */
+        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+        psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+        /* set new field's value to NULL */
+        memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
+
+        nRecordOffset = psDBF->nRecordLength * (SAOffset) i + psDBF->nHeaderLength;
+
+        /* move record to the new place*/
+        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+        psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+    }
+
+    /* free record */
+    free(pszRecord);
+
+    /* force update of header with new header, record length and new field */
+    psDBF->bNoHeader = TRUE;
+    DBFUpdateHeader( psDBF );
+
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
 
     return( psDBF->nFields-1 );
 }
@@ -687,12 +953,9 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
                               char chReqType )
 
 {
-    int	       	nRecordOffset;
     unsigned char	*pabyRec;
     void	*pReturnField = NULL;
 
-    static double dDoubleField;
-
 /* -------------------------------------------------------------------- */
 /*      Verify selection.                                               */
 /* -------------------------------------------------------------------- */
@@ -705,59 +968,42 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
 /* -------------------------------------------------------------------- */
 /*	Have we read the record?					*/
 /* -------------------------------------------------------------------- */
-    if( psDBF->nCurrentRecord != hEntity )
-    {
-	DBFFlushRecord( psDBF );
-
-	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
-	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
-        {
-            fprintf( stderr, "fseek(%d) failed on DBF file.\n",
-                     nRecordOffset );
-            return NULL;
-        }
-
-	if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 
-                   1, psDBF->fp ) != 1 )
-        {
-            fprintf( stderr, "fread(%d) failed on DBF file.\n",
-                     psDBF->nRecordLength );
-            return NULL;
-        }
-
-	psDBF->nCurrentRecord = hEntity;
-    }
+    if( !DBFLoadRecord( psDBF, hEntity ) )
+        return NULL;
 
     pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
 /* -------------------------------------------------------------------- */
-/*	Ensure our field buffer is large enough to hold this buffer.	*/
+/*      Ensure we have room to extract the target field.                */
 /* -------------------------------------------------------------------- */
-    if( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
+    if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength )
     {
-	nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
-	pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
+        psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100;
+        if( psDBF->pszWorkField == NULL )
+            psDBF->pszWorkField = (char *) malloc(psDBF->nWorkFieldLength);
+        else
+            psDBF->pszWorkField = (char *) realloc(psDBF->pszWorkField,
+                                                   psDBF->nWorkFieldLength);
     }
 
 /* -------------------------------------------------------------------- */
 /*	Extract the requested field.					*/
 /* -------------------------------------------------------------------- */
-    strncpy( pszStringField, 
+    strncpy( psDBF->pszWorkField,
 	     ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
 	     psDBF->panFieldSize[iField] );
-    pszStringField[psDBF->panFieldSize[iField]] = '\0';
+    psDBF->pszWorkField[psDBF->panFieldSize[iField]] = '\0';
 
-    pReturnField = pszStringField;
+    pReturnField = psDBF->pszWorkField;
 
 /* -------------------------------------------------------------------- */
 /*      Decode the field.                                               */
 /* -------------------------------------------------------------------- */
     if( chReqType == 'N' )
     {
-        dDoubleField = atof(pszStringField);
+        psDBF->dfDoubleField = psDBF->sHooks.Atof(psDBF->pszWorkField);
 
-	pReturnField = &dDoubleField;
+	pReturnField = &(psDBF->dfDoubleField);
     }
 
 /* -------------------------------------------------------------------- */
@@ -768,7 +1014,7 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
     {
         char	*pchSrc, *pchDst;
 
-        pchDst = pchSrc = pszStringField;
+        pchDst = pchSrc = psDBF->pszWorkField;
         while( *pchSrc == ' ' )
             pchSrc++;
 
@@ -776,7 +1022,7 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
             *(pchDst++) = *(pchSrc++);
         *pchDst = '\0';
 
-        while( pchDst != pszStringField && *(--pchDst) == ' ' )
+        while( pchDst != psDBF->pszWorkField && *(--pchDst) == ' ' )
             *pchDst = '\0';
     }
 #endif
@@ -850,35 +1096,45 @@ DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
     return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
 }
 
+
 /************************************************************************/
-/*                         DBFIsAttributeNULL()                         */
-/*                                                                      */
-/*      Return TRUE if value for field is NULL.                         */
+/*                         DBFIsValueNULL()                             */
 /*                                                                      */
-/*      Contributed by Jim Matthews.                                    */
+/*      Return TRUE if the passed string is NULL.                       */
 /************************************************************************/
 
-int SHPAPI_CALL
-DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
-
+static int DBFIsValueNULL( char chType, const char* pszValue )
 {
-    const char	*pszValue;
+    int i;
 
-    pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+    if( pszValue == NULL )
+        return TRUE;
 
-    switch(psDBF->pachFieldType[iField])
+    switch(chType)
     {
       case 'N':
       case 'F':
-        /* NULL numeric fields have value "****************" */
-        return pszValue[0] == '*';
+        /*
+        ** We accept all asterisks or all blanks as NULL
+        ** though according to the spec I think it should be all
+        ** asterisks.
+        */
+        if( pszValue[0] == '*' )
+            return TRUE;
+
+        for( i = 0; pszValue[i] != '\0'; i++ )
+        {
+            if( pszValue[i] != ' ' )
+                return FALSE;
+        }
+        return TRUE;
 
       case 'D':
         /* NULL date fields have value "00000000" */
         return strncmp(pszValue,"00000000",8) == 0;
 
       case 'L':
-        /* NULL boolean fields have value "?" */ 
+        /* NULL boolean fields have value "?" */
         return pszValue[0] == '?';
 
       default:
@@ -888,20 +1144,42 @@ DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
 }
 
 /************************************************************************/
-/*                          DBFGetFieldCount()                          */
+/*                         DBFIsAttributeNULL()                         */
 /*                                                                      */
-/*      Return the number of fields in this table.                      */
+/*      Return TRUE if value for field is NULL.                         */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
 /************************************************************************/
 
 int SHPAPI_CALL
-DBFGetFieldCount( DBFHandle psDBF )
+DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
 
 {
-    return( psDBF->nFields );
+    const char	*pszValue;
+
+    pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+
+    if( pszValue == NULL )
+        return TRUE;
+
+    return DBFIsValueNULL( psDBF->pachFieldType[iField], pszValue );
 }
 
 /************************************************************************/
-/*                         DBFGetRecordCount()                          */
+/*                          DBFGetFieldCount()                          */
+/*                                                                      */
+/*      Return the number of fields in this table.                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldCount( DBFHandle psDBF )
+
+{
+    return( psDBF->nFields );
+}
+
+/************************************************************************/
+/*                         DBFGetRecordCount()                          */
 /*                                                                      */
 /*      Return the number of records in this table.                     */
 /************************************************************************/
@@ -947,10 +1225,10 @@ DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
 	return( FTLogical);
 
     else if( psDBF->pachFieldType[iField] == 'N' 
-             || psDBF->pachFieldType[iField] == 'F'
-             || psDBF->pachFieldType[iField] == 'D' )
+             || psDBF->pachFieldType[iField] == 'F' )
     {
-	if( psDBF->panFieldDecimals[iField] > 0 )
+	if( psDBF->panFieldDecimals[iField] > 0 
+            || psDBF->panFieldSize[iField] > 10 )
 	    return( FTDouble );
 	else
 	    return( FTInteger );
@@ -971,7 +1249,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 			     void * pValue )
 
 {
-    int	       	nRecordOffset, i, j, nRetResult = TRUE;
+    int	       	i, j, nRetResult = TRUE;
     unsigned char	*pabyRec;
     char	szSField[400], szFormat[20];
 
@@ -989,7 +1267,8 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 /* -------------------------------------------------------------------- */
     if( hEntity == psDBF->nRecords )
     {
-	DBFFlushRecord( psDBF );
+	if( !DBFFlushRecord( psDBF ) )
+            return FALSE;
 
 	psDBF->nRecords++;
 	for( i = 0; i < psDBF->nRecordLength; i++ )
@@ -1002,17 +1281,8 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 /*      Is this an existing record, but different than the last one     */
 /*      we accessed?                                                    */
 /* -------------------------------------------------------------------- */
-    if( psDBF->nCurrentRecord != hEntity )
-    {
-	DBFFlushRecord( psDBF );
-
-	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
-	fseek( psDBF->fp, nRecordOffset, 0 );
-	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
-	psDBF->nCurrentRecord = hEntity;
-    }
+    if( !DBFLoadRecord( psDBF, hEntity ) )
+        return FALSE;
 
     pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
@@ -1026,33 +1296,9 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 /* -------------------------------------------------------------------- */
     if( pValue == NULL )
     {
-        switch(psDBF->pachFieldType[iField])
-        {
-          case 'N':
-          case 'F':
-	    /* NULL numeric fields have value "****************" */
-            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', 
-                    psDBF->panFieldSize[iField] );
-            break;
-
-          case 'D':
-	    /* NULL date fields have value "00000000" */
-            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', 
-                    psDBF->panFieldSize[iField] );
-            break;
-
-          case 'L':
-	    /* NULL boolean fields have value "?" */ 
-            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', 
-                    psDBF->panFieldSize[iField] );
-            break;
-
-          default:
-            /* empty string fields are considered NULL */
-            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', 
-                    psDBF->panFieldSize[iField] );
-            break;
-        }
+        memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]),
+                DBFGetNullCharacter(psDBF->pachFieldType[iField]),
+                psDBF->panFieldSize[iField] );
         return TRUE;
     }
 
@@ -1068,7 +1314,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 	{
             int		nWidth = psDBF->panFieldSize[iField];
 
-            if( sizeof(szSField)-2 < nWidth )
+            if( (int) sizeof(szSField)-2 < nWidth )
                 nWidth = sizeof(szSField)-2;
 
 	    sprintf( szFormat, "%%%dd", nWidth );
@@ -1086,7 +1332,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 	{
             int		nWidth = psDBF->panFieldSize[iField];
 
-            if( sizeof(szSField)-2 < nWidth )
+            if( (int) sizeof(szSField)-2 < nWidth )
                 nWidth = sizeof(szSField)-2;
 
 	    sprintf( szFormat, "%%%d.%df", 
@@ -1137,11 +1383,12 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
 /*      as is to the field position in the record.                      */
 /************************************************************************/
 
-int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
+int SHPAPI_CALL
+DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
                               void * pValue )
 
 {
-    int	       	nRecordOffset, i, j;
+    int	       		i, j;
     unsigned char	*pabyRec;
 
 /* -------------------------------------------------------------------- */
@@ -1158,7 +1405,8 @@ int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
 /* -------------------------------------------------------------------- */
     if( hEntity == psDBF->nRecords )
     {
-	DBFFlushRecord( psDBF );
+	if( !DBFFlushRecord( psDBF ) )
+            return FALSE;
 
 	psDBF->nRecords++;
 	for( i = 0; i < psDBF->nRecordLength; i++ )
@@ -1171,17 +1419,8 @@ int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
 /*      Is this an existing record, but different than the last one     */
 /*      we accessed?                                                    */
 /* -------------------------------------------------------------------- */
-    if( psDBF->nCurrentRecord != hEntity )
-    {
-	DBFFlushRecord( psDBF );
-
-	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
-	fseek( psDBF->fp, nRecordOffset, 0 );
-	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
-	psDBF->nCurrentRecord = hEntity;
-    }
+    if( !DBFLoadRecord( psDBF, hEntity ) )
+        return FALSE;
 
     pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
@@ -1287,7 +1526,7 @@ int SHPAPI_CALL
 DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
 
 {
-    int	       	nRecordOffset, i;
+    int	       		i;
     unsigned char	*pabyRec;
 
 /* -------------------------------------------------------------------- */
@@ -1304,7 +1543,8 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
 /* -------------------------------------------------------------------- */
     if( hEntity == psDBF->nRecords )
     {
-	DBFFlushRecord( psDBF );
+	if( !DBFFlushRecord( psDBF ) )
+            return FALSE;
 
 	psDBF->nRecords++;
 	for( i = 0; i < psDBF->nRecordLength; i++ )
@@ -1317,17 +1557,8 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
 /*      Is this an existing record, but different than the last one     */
 /*      we accessed?                                                    */
 /* -------------------------------------------------------------------- */
-    if( psDBF->nCurrentRecord != hEntity )
-    {
-	DBFFlushRecord( psDBF );
-
-	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
-	fseek( psDBF->fp, nRecordOffset, 0 );
-	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
-	psDBF->nCurrentRecord = hEntity;
-    }
+    if( !DBFLoadRecord( psDBF, hEntity ) )
+        return FALSE;
 
     pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
@@ -1340,49 +1571,23 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
 }
 
 /************************************************************************/
-/*                          DBFReadTuple()                              */
+/*                            DBFReadTuple()                            */
 /*                                                                      */
-/*      Read one of the attribute fields of a record.                   */
+/*      Read a complete record.  Note that the result is only valid     */
+/*      till the next record read for any reason.                       */
 /************************************************************************/
 
 const char SHPAPI_CALL1(*)
 DBFReadTuple(DBFHandle psDBF, int hEntity )
 
 {
-    int	       	nRecordOffset;
-    unsigned char	*pabyRec;
-    static char	*pReturnTuple = NULL;
-
-    static int	nTupleLen = 0;
-
-/* -------------------------------------------------------------------- */
-/*	Have we read the record?					*/
-/* -------------------------------------------------------------------- */
     if( hEntity < 0 || hEntity >= psDBF->nRecords )
         return( NULL );
 
-    if( psDBF->nCurrentRecord != hEntity )
-    {
-	DBFFlushRecord( psDBF );
-
-	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
-	fseek( psDBF->fp, nRecordOffset, 0 );
-	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
-	psDBF->nCurrentRecord = hEntity;
-    }
-
-    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+    if( !DBFLoadRecord( psDBF, hEntity ) )
+        return NULL;
 
-    if ( nTupleLen < psDBF->nRecordLength) {
-      nTupleLen = psDBF->nRecordLength;
-      pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
-    }
-    
-    memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
-        
-    return( pReturnTuple );
+    return (const char *) psDBF->pszCurrentRecord;
 }
 
 /************************************************************************/
@@ -1396,24 +1601,24 @@ DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
 {
     DBFHandle	newDBF;
 
-   newDBF = DBFCreate ( pszFilename );
+   newDBF = DBFCreateEx ( pszFilename, psDBF->pszCodePage );
    if ( newDBF == NULL ) return ( NULL ); 
    
-   newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
-   memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
-   
    newDBF->nFields = psDBF->nFields;
    newDBF->nRecordLength = psDBF->nRecordLength;
-   newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
+   newDBF->nHeaderLength = psDBF->nHeaderLength;
     
+   newDBF->pszHeader = (char *) malloc ( newDBF->nHeaderLength );
+   memcpy ( newDBF->pszHeader, psDBF->pszHeader, newDBF->nHeaderLength );
+   
    newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); 
    memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
    newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
    memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
    newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
    memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
-   newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
-   memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
+   newDBF->pachFieldType = (char *) malloc ( sizeof(char) * psDBF->nFields );
+   memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(char)*psDBF->nFields );
 
    newDBF->bNoHeader = TRUE;
    newDBF->bUpdated = TRUE;
@@ -1460,7 +1665,7 @@ static void str_to_upper (char *string)
 
     while (++i < len)
         if (isalpha(string[i]) && islower(string[i]))
-            string[i] = toupper ((int)string[i]);
+            string[i] = (char) toupper ((int)string[i]);
 }
 
 /************************************************************************/
@@ -1493,3 +1698,524 @@ DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
     }
     return(-1);
 }
+
+/************************************************************************/
+/*                         DBFIsRecordDeleted()                         */
+/*                                                                      */
+/*      Returns TRUE if the indicated record is deleted, otherwise      */
+/*      it returns FALSE.                                               */
+/************************************************************************/
+
+int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Verify selection.                                               */
+/* -------------------------------------------------------------------- */
+    if( iShape < 0 || iShape >= psDBF->nRecords )
+        return TRUE;
+
+/* -------------------------------------------------------------------- */
+/*	Have we read the record?					*/
+/* -------------------------------------------------------------------- */
+    if( !DBFLoadRecord( psDBF, iShape ) )
+        return FALSE;
+
+/* -------------------------------------------------------------------- */
+/*      '*' means deleted.                                              */
+/* -------------------------------------------------------------------- */
+    return psDBF->pszCurrentRecord[0] == '*';
+}
+
+/************************************************************************/
+/*                        DBFMarkRecordDeleted()                        */
+/************************************************************************/
+
+int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape, 
+                                      int bIsDeleted )
+
+{
+    char chNewFlag;
+
+/* -------------------------------------------------------------------- */
+/*      Verify selection.                                               */
+/* -------------------------------------------------------------------- */
+    if( iShape < 0 || iShape >= psDBF->nRecords )
+        return FALSE;
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( !DBFLoadRecord( psDBF, iShape ) )
+        return FALSE;
+
+/* -------------------------------------------------------------------- */
+/*      Assign value, marking record as dirty if it changes.            */
+/* -------------------------------------------------------------------- */
+    if( bIsDeleted )
+        chNewFlag = '*';
+    else 
+        chNewFlag = ' ';
+
+    if( psDBF->pszCurrentRecord[0] != chNewFlag )
+    {
+        psDBF->bCurrentRecordModified = TRUE;
+        psDBF->bUpdated = TRUE;
+        psDBF->pszCurrentRecord[0] = chNewFlag;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                            DBFGetCodePage                            */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFGetCodePage(DBFHandle psDBF )
+{
+    if( psDBF == NULL )
+        return NULL;
+    return psDBF->pszCodePage;
+}
+
+/************************************************************************/
+/*                          DBFDeleteField()                            */
+/*                                                                      */
+/*      Remove a field from a .dbf file                                 */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFDeleteField(DBFHandle psDBF, int iField)
+{
+    int nOldRecordLength, nOldHeaderLength;
+    int nDeletedFieldOffset, nDeletedFieldSize;
+    SAOffset nRecordOffset;
+    char* pszRecord;
+    int i, iRecord;
+
+    if (iField < 0 || iField >= psDBF->nFields)
+        return FALSE;
+
+    /* make sure that everything is written in .dbf */
+    if( !DBFFlushRecord( psDBF ) )
+        return FALSE;
+
+    /* get information about field to be deleted */
+    nOldRecordLength = psDBF->nRecordLength;
+    nOldHeaderLength = psDBF->nHeaderLength;
+    nDeletedFieldOffset = psDBF->panFieldOffset[iField];
+    nDeletedFieldSize = psDBF->panFieldSize[iField];
+
+    /* update fields info */
+    for (i = iField + 1; i < psDBF->nFields; i++)
+    {
+        psDBF->panFieldOffset[i-1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
+        psDBF->panFieldSize[i-1] = psDBF->panFieldSize[i];
+        psDBF->panFieldDecimals[i-1] = psDBF->panFieldDecimals[i];
+        psDBF->pachFieldType[i-1] = psDBF->pachFieldType[i];
+    }
+
+    /* resize fields arrays */
+    psDBF->nFields--;
+
+    psDBF->panFieldOffset = (int *) 
+        SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+
+    psDBF->panFieldSize = (int *) 
+        SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+
+    psDBF->panFieldDecimals = (int *) 
+        SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+
+    psDBF->pachFieldType = (char *) 
+        SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+
+    /* update header information */
+    psDBF->nHeaderLength -= 32;
+    psDBF->nRecordLength -= nDeletedFieldSize;
+
+    /* overwrite field information in header */
+    memmove(psDBF->pszHeader + iField*32,
+           psDBF->pszHeader + (iField+1)*32,
+           sizeof(char) * (psDBF->nFields - iField)*32);
+
+    psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
+
+    /* update size of current record appropriately */
+    psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+                                                 psDBF->nRecordLength);
+
+    /* we're done if we're dealing with not yet created .dbf */
+    if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+        return TRUE;
+
+    /* force update of header with new header and record length */
+    psDBF->bNoHeader = TRUE;
+    DBFUpdateHeader( psDBF );
+
+    /* alloc record */
+    pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
+
+    /* shift records to their new positions */
+    for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+    {
+        nRecordOffset = 
+            nOldRecordLength * (SAOffset) iRecord + nOldHeaderLength;
+
+        /* load record */
+        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+        psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+        nRecordOffset = 
+            psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+        /* move record in two steps */
+        psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+        psDBF->sHooks.FWrite( pszRecord, nDeletedFieldOffset, 1, psDBF->fp );
+        psDBF->sHooks.FWrite( pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
+                              nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
+                              1, psDBF->fp );
+
+    }
+
+    /* TODO: truncate file */
+
+    /* free record */
+    free(pszRecord);
+
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                          DBFReorderFields()                          */
+/*                                                                      */
+/*      Reorder the fields of a .dbf file                               */
+/*                                                                      */
+/* panMap must be exactly psDBF->nFields long and be a permutation      */
+/* of [0, psDBF->nFields-1]. This assumption will not be asserted in the*/
+/* code of DBFReorderFields.                                            */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFReorderFields( DBFHandle psDBF, int* panMap )
+{
+    SAOffset nRecordOffset;
+    int      i, iRecord;
+    int     *panFieldOffsetNew;
+    int     *panFieldSizeNew;
+    int     *panFieldDecimalsNew;
+    char    *pachFieldTypeNew;
+    char    *pszHeaderNew;
+    char    *pszRecord;
+    char    *pszRecordNew;
+
+    if ( psDBF->nFields == 0 )
+        return TRUE;
+
+    /* make sure that everything is written in .dbf */
+    if( !DBFFlushRecord( psDBF ) )
+        return FALSE;
+
+    panFieldOffsetNew = (int *) malloc(sizeof(int) * psDBF->nFields);
+    panFieldSizeNew = (int *) malloc(sizeof(int) *  psDBF->nFields);
+    panFieldDecimalsNew = (int *) malloc(sizeof(int) *  psDBF->nFields);
+    pachFieldTypeNew = (char *) malloc(sizeof(char) *  psDBF->nFields);
+    pszHeaderNew = (char*) malloc(sizeof(char) * 32 *  psDBF->nFields);
+
+    /* shuffle fields definitions */
+    for(i=0; i < psDBF->nFields; i++)
+    {
+        panFieldSizeNew[i] = psDBF->panFieldSize[panMap[i]];
+        panFieldDecimalsNew[i] = psDBF->panFieldDecimals[panMap[i]];
+        pachFieldTypeNew[i] = psDBF->pachFieldType[panMap[i]];
+        memcpy(pszHeaderNew + i * 32,
+               psDBF->pszHeader + panMap[i] * 32, 32);
+    }
+    panFieldOffsetNew[0] = 1;
+    for(i=1; i < psDBF->nFields; i++)
+    {
+        panFieldOffsetNew[i] = panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
+    }
+
+    free(psDBF->pszHeader);
+    psDBF->pszHeader = pszHeaderNew;
+
+    /* we're done if we're dealing with not yet created .dbf */
+    if ( !(psDBF->bNoHeader && psDBF->nRecords == 0) )
+    {
+        /* force update of header with new header and record length */
+        psDBF->bNoHeader = TRUE;
+        DBFUpdateHeader( psDBF );
+
+        /* alloc record */
+        pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+        pszRecordNew = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+
+        /* shuffle fields in records */
+        for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+        {
+            nRecordOffset =
+                psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+            /* load record */
+            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+            psDBF->sHooks.FRead( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+            pszRecordNew[0] = pszRecord[0];
+
+            for(i=0; i < psDBF->nFields; i++)
+            {
+                memcpy(pszRecordNew + panFieldOffsetNew[i],
+                       pszRecord + psDBF->panFieldOffset[panMap[i]],
+                       psDBF->panFieldSize[panMap[i]]);
+            }
+
+            /* write record */
+            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+            psDBF->sHooks.FWrite( pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp );
+        }
+
+        /* free record */
+        free(pszRecord);
+        free(pszRecordNew);
+    }
+
+    free(psDBF->panFieldOffset);
+    free(psDBF->panFieldSize);
+    free(psDBF->panFieldDecimals);
+    free(psDBF->pachFieldType);
+
+    psDBF->panFieldOffset = panFieldOffsetNew;
+    psDBF->panFieldSize = panFieldSizeNew;
+    psDBF->panFieldDecimals =panFieldDecimalsNew;
+    psDBF->pachFieldType = pachFieldTypeNew;
+
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+
+    return TRUE;
+}
+
+
+/************************************************************************/
+/*                          DBFAlterFieldDefn()                         */
+/*                                                                      */
+/*      Alter a field definition in a .dbf file                         */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
+                    char chType, int nWidth, int nDecimals )
+{
+    int   i;
+    int   iRecord;
+    int   nOffset;
+    int   nOldWidth;
+    int   nOldRecordLength;
+    int   nRecordOffset;
+    char* pszFInfo;
+    char  chOldType;
+    int   bIsNULL;
+    char chFieldFill;
+
+    if (iField < 0 || iField >= psDBF->nFields)
+        return FALSE;
+
+    /* make sure that everything is written in .dbf */
+    if( !DBFFlushRecord( psDBF ) )
+        return FALSE;
+
+    chFieldFill = DBFGetNullCharacter(chType);
+
+    chOldType = psDBF->pachFieldType[iField];
+    nOffset = psDBF->panFieldOffset[iField];
+    nOldWidth = psDBF->panFieldSize[iField];
+    nOldRecordLength = psDBF->nRecordLength;
+
+/* -------------------------------------------------------------------- */
+/*      Do some checking to ensure we can add records to this file.     */
+/* -------------------------------------------------------------------- */
+    if( nWidth < 1 )
+        return -1;
+
+    if( nWidth > 255 )
+        nWidth = 255;
+
+/* -------------------------------------------------------------------- */
+/*      Assign the new field information fields.                        */
+/* -------------------------------------------------------------------- */
+    psDBF->panFieldSize[iField] = nWidth;
+    psDBF->panFieldDecimals[iField] = nDecimals;
+    psDBF->pachFieldType[iField] = chType;
+
+/* -------------------------------------------------------------------- */
+/*      Update the header information.                                  */
+/* -------------------------------------------------------------------- */
+    pszFInfo = psDBF->pszHeader + 32 * iField;
+
+    for( i = 0; i < 32; i++ )
+        pszFInfo[i] = '\0';
+
+    if( (int) strlen(pszFieldName) < 10 )
+        strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
+    else
+        strncpy( pszFInfo, pszFieldName, 10);
+
+    pszFInfo[11] = psDBF->pachFieldType[iField];
+
+    if( chType == 'C' )
+    {
+        pszFInfo[16] = (unsigned char) (nWidth % 256);
+        pszFInfo[17] = (unsigned char) (nWidth / 256);
+    }
+    else
+    {
+        pszFInfo[16] = (unsigned char) nWidth;
+        pszFInfo[17] = (unsigned char) nDecimals;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Update offsets                                                  */
+/* -------------------------------------------------------------------- */
+    if (nWidth != nOldWidth)
+    {
+        for (i = iField + 1; i < psDBF->nFields; i++)
+             psDBF->panFieldOffset[i] += nWidth - nOldWidth;
+        psDBF->nRecordLength += nWidth - nOldWidth;
+
+        psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+                                                     psDBF->nRecordLength);
+    }
+
+    /* we're done if we're dealing with not yet created .dbf */
+    if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+        return TRUE;
+
+    /* force update of header with new header and record length */
+    psDBF->bNoHeader = TRUE;
+    DBFUpdateHeader( psDBF );
+
+    if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
+    {
+        char* pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
+        char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1));
+
+        pszOldField[nOldWidth] = 0;
+
+        /* move records to their new positions */
+        for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+        {
+            nRecordOffset =
+                nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+            /* load record */
+            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+            psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+            memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
+            bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
+
+            if (nWidth != nOldWidth)
+            {
+                if ((chOldType == 'N' || chOldType == 'F') && pszOldField[0] == ' ')
+                {
+                    /* Strip leading spaces when truncating a numeric field */
+                    memmove( pszRecord + nOffset,
+                            pszRecord + nOffset + nOldWidth - nWidth,
+                            nWidth );
+                }
+                if (nOffset + nOldWidth < nOldRecordLength)
+                {
+                    memmove( pszRecord + nOffset + nWidth,
+                            pszRecord + nOffset + nOldWidth,
+                            nOldRecordLength - (nOffset + nOldWidth));
+                }
+            }
+
+            /* Convert null value to the appropriate value of the new type */
+            if (bIsNULL)
+            {
+                memset( pszRecord + nOffset, chFieldFill, nWidth);
+            }
+
+            nRecordOffset =
+                psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+            /* write record */
+            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+            psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+        }
+
+        free(pszRecord);
+        free(pszOldField);
+    }
+    else if (nWidth > nOldWidth)
+    {
+        char* pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+        char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1));
+
+        pszOldField[nOldWidth] = 0;
+
+        /* move records to their new positions */
+        for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
+        {
+            nRecordOffset =
+                nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+            /* load record */
+            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+            psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+            memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
+            bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
+
+            if (nOffset + nOldWidth < nOldRecordLength)
+            {
+                memmove( pszRecord + nOffset + nWidth,
+                         pszRecord + nOffset + nOldWidth,
+                         nOldRecordLength - (nOffset + nOldWidth));
+            }
+
+            /* Convert null value to the appropriate value of the new type */
+            if (bIsNULL)
+            {
+                memset( pszRecord + nOffset, chFieldFill, nWidth);
+            }
+            else
+            {
+                if ((chOldType == 'N' || chOldType == 'F'))
+                {
+                    /* Add leading spaces when expanding a numeric field */
+                    memmove( pszRecord + nOffset + nWidth - nOldWidth,
+                             pszRecord + nOffset, nOldWidth );
+                    memset( pszRecord + nOffset, ' ', nWidth - nOldWidth );
+                }
+                else
+                {
+                    /* Add trailing spaces */
+                    memset(pszRecord + nOffset + nOldWidth, ' ', nWidth - nOldWidth);
+                }
+            }
+
+            nRecordOffset =
+                psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+            /* write record */
+            psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+            psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+        }
+
+        free(pszRecord);
+        free(pszOldField);
+    }
+
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+
+    return TRUE;
+}
diff --git a/libtool b/libtool
deleted file mode 100755
index 7706a8c..0000000
--- a/libtool
+++ /dev/null
@@ -1,4149 +0,0 @@
-#! /bin/sh
-
-# libtool - Provide generalized library-building support services.
-# Generated automatically by ltconfig (GNU libtool 1.3 (1.385.2.117 1999/04/29 13:07:13))
-# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
-#
-# Copyright (C) 1996-1999 Free Software Foundation, Inc.
-# Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
-#
-# 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.
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="sed -e s/^X//"
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
-
-### BEGIN LIBTOOL CONFIG
-# Libtool was configured as follows, on host cs46980-c:
-#
-# CC="gcc" CFLAGS="-g -O2" CPPFLAGS="" \
-# LD="/usr/bin/ld" LDFLAGS="" LIBS="" \
-# NM="/usr/bin/nm -B" RANLIB="ranlib" LN_S="ln -s" \
-# DLLTOOL="" OBJDUMP="" AS="" \
-#   ./ltconfig --cache-file=./config.cache --with-gcc --with-gnu-ld --no-verify ./ltmain.sh i586-pc-linux-gnu
-#
-# Compiler and other test output produced by ltconfig, useful for
-# debugging ltconfig, is in ./config.log if it exists.
-
-# The version of ltconfig that generated this script.
-LTCONFIG_VERSION="1.3"
-
-# Shell to use when invoking shell scripts.
-SHELL="/bin/sh"
-
-# Whether or not to build shared libraries.
-build_libtool_libs=yes
-
-# Whether or not to build static libraries.
-build_old_libs=yes
-
-# Whether or not to optimize for fast installation.
-fast_install=yes
-
-# The host system.
-host_alias=i586-pc-linux-gnu
-host=i586-pc-linux-gnu
-
-# An echo program that does not interpret backslashes.
-echo="echo"
-
-# The archiver.
-AR="ar"
-
-# The default C compiler.
-CC="gcc"
-
-# The linker used to build libraries.
-LD="/usr/bin/ld"
-
-# Whether we need hard or soft links.
-LN_S="ln -s"
-
-# A BSD-compatible nm program.
-NM="/usr/bin/nm -B"
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="dlltool"
-
-# Used on cygwin: object dumper.
-OBJDUMP="objdump"
-
-# Used on cygwin: assembler.
-AS="as"
-
-# The name of the directory that contains temporary libtool files.
-objdir=.libs
-
-# How to create reloadable object files.
-reload_flag=" -r"
-reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs"
-
-# How to pass a linker flag through the compiler.
-wl="-Wl,"
-
-# Object file suffix (normally "o").
-objext="o"
-
-# Old archive suffix (normally "a").
-libext="a"
-
-# Additional compiler flags for building library objects.
-pic_flag=" -fPIC"
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o="yes"
-
-# Can we write directly to a .lo ?
-compiler_o_lo="yes"
-
-# Must we lock files when doing compilation ?
-need_locks="no"
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=no
-
-# Do we need a version for libraries?
-need_version=no
-
-# Whether dlopen is supported.
-dlopen=unknown
-
-# Whether dlopen of programs is supported.
-dlopen_self=unknown
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=unknown
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag="-static"
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions"
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec="\${wl}--export-dynamic"
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive"
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=""
-
-# Library versioning type.
-version_type=linux
-
-# Format of library name prefix.
-libname_spec="lib\$name"
-
-# List of archive names.  First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec="\${libname}\${release}.so\$versuffix \${libname}\${release}.so\$major \$libname.so"
-
-# The coded name of the library, if different from the real name.
-soname_spec="\${libname}\${release}.so\$major"
-
-# Commands used to build and install an old-style archive.
-RANLIB="ranlib"
-old_archive_cmds="\$AR cru \$oldlib\$oldobjs~\$RANLIB \$oldlib"
-old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib"
-old_postuninstall_cmds=""
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=""
-
-# Commands used to build and install a shared archive.
-archive_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname -o \$lib"
-archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib"
-postinstall_cmds=""
-postuninstall_cmds=""
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )"
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd="/usr/bin/file"
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=""
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=""
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir"
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=""
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe="sed -n -e 's/^.*[ 	]\\([ABCDGISTW]\\)[ 	][ 	]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'"
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern char \\1;/p'"
-
-# This is the shared library runtime path variable.
-runpath_var=LD_RUN_PATH
-
-# This is the shared library path variable.
-shlibpath_var=LD_LIBRARY_PATH
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=no
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=immediate
-
-# Flag to hardcode $libdir into a binary during linking.
-# This must work even if $libdir does not exist.
-hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir"
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=""
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=no
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=no
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=unsupported
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-
-# Fix the shell variable $srcfile for the compiler.
-fix_srcfile_path=""
-
-# Set to yes if exported symbols are required.
-always_export_symbols=no
-
-# The commands to list exported symbols.
-export_symbols_cmds="\$NM \$libobjs | \$global_symbol_pipe | sed 's/.* //' | sort | uniq > \$export_symbols"
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
-
-# Symbols that must always be exported.
-include_expsyms=""
-
-### END LIBTOOL CONFIG
-
-# ltmain.sh - Provide generalized library-building support services.
-# NOTE: Changing this file will not affect anything until you rerun ltconfig.
-#
-# Copyright (C) 1996-1999 Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
-#
-# 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.
-
-# Check that we have a working $echo.
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
-  # Yippee, $echo works!
-  :
-else
-  # Restart under the correct shell, and then maybe $echo will work.
-  exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<EOF
-$*
-EOF
-  exit 0
-fi
-
-# The name of this program.
-progname=`$echo "$0" | sed 's%^.*/%%'`
-modename="$progname"
-
-# Constants.
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION=1.3
-TIMESTAMP=" (1.385.2.117 1999/04/29 13:07:13)"
-
-default_mode=
-help="Try \`$progname --help' for more information."
-magic="%%%MAGIC variable%%%"
-mkdir="mkdir"
-mv="mv -f"
-rm="rm -f"
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-SP2NL='tr \040 \012'
-NL2SP='tr \012 \040'
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-# We save the old values to restore during execute mode.
-if test "${LC_ALL+set}" = set; then
-  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
-fi
-if test "${LANG+set}" = set; then
-  save_LANG="$LANG"; LANG=C; export LANG
-fi
-
-if test "$LTCONFIG_VERSION" != "$VERSION"; then
-  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
-  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-  exit 1
-fi
-
-if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
-  echo "$modename: not configured to build any kind of library" 1>&2
-  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-  exit 1
-fi
-
-# Global variables.
-mode=$default_mode
-nonopt=
-prev=
-prevopt=
-run=
-show="$echo"
-show_help=
-execute_dlfiles=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-
-# Parse our command line options once, thoroughly.
-while test $# -gt 0
-do
-  arg="$1"
-  shift
-
-  case "$arg" in
-  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) optarg= ;;
-  esac
-
-  # If the previous option needs an argument, assign it.
-  if test -n "$prev"; then
-    case "$prev" in
-    execute_dlfiles)
-      eval "$prev=\"\$$prev \$arg\""
-      ;;
-    *)
-      eval "$prev=\$arg"
-      ;;
-    esac
-
-    prev=
-    prevopt=
-    continue
-  fi
-
-  # Have we seen a non-optional argument yet?
-  case "$arg" in
-  --help)
-    show_help=yes
-    ;;
-
-  --version)
-    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
-    exit 0
-    ;;
-
-  --config)
-    sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
-    exit 0
-    ;;
-
-  --debug)
-    echo "$progname: enabling shell trace mode"
-    set -x
-    ;;
-
-  --dry-run | -n)
-    run=:
-    ;;
-
-  --features)
-    echo "host: $host"
-    if test "$build_libtool_libs" = yes; then
-      echo "enable shared libraries"
-    else
-      echo "disable shared libraries"
-    fi
-    if test "$build_old_libs" = yes; then
-      echo "enable static libraries"
-    else
-      echo "disable static libraries"
-    fi
-    exit 0
-    ;;
-
-  --finish) mode="finish" ;;
-
-  --mode) prevopt="--mode" prev=mode ;;
-  --mode=*) mode="$optarg" ;;
-
-  --quiet | --silent)
-    show=:
-    ;;
-
-  -dlopen)
-    prevopt="-dlopen"
-    prev=execute_dlfiles
-    ;;
-
-  -*)
-    $echo "$modename: unrecognized option \`$arg'" 1>&2
-    $echo "$help" 1>&2
-    exit 1
-    ;;
-
-  *)
-    nonopt="$arg"
-    break
-    ;;
-  esac
-done
-
-if test -n "$prevopt"; then
-  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
-  $echo "$help" 1>&2
-  exit 1
-fi
-
-if test -z "$show_help"; then
-
-  # Infer the operation mode.
-  if test -z "$mode"; then
-    case "$nonopt" in
-    *cc | *++ | gcc* | *-gcc*)
-      mode=link
-      for arg
-      do
-	case "$arg" in
-	-c)
-	   mode=compile
-	   break
-	   ;;
-	esac
-      done
-      ;;
-    *db | *dbx | *strace | *truss)
-      mode=execute
-      ;;
-    *install*|cp|mv)
-      mode=install
-      ;;
-    *rm)
-      mode=uninstall
-      ;;
-    *)
-      # If we have no mode, but dlfiles were specified, then do execute mode.
-      test -n "$execute_dlfiles" && mode=execute
-
-      # Just use the default operation mode.
-      if test -z "$mode"; then
-	if test -n "$nonopt"; then
-	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
-	else
-	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
-	fi
-      fi
-      ;;
-    esac
-  fi
-
-  # Only execute mode is allowed to have -dlopen flags.
-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
-    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
-    $echo "$help" 1>&2
-    exit 1
-  fi
-
-  # Change the help message to a mode-specific one.
-  generic_help="$help"
-  help="Try \`$modename --help --mode=$mode' for more information."
-
-  # These modes are in order of execution frequency so that they run quickly.
-  case "$mode" in
-  # libtool compile mode
-  compile)
-    modename="$modename: compile"
-    # Get the compilation command and the source file.
-    base_compile=
-    lastarg=
-    srcfile="$nonopt"
-    suppress_output=
-
-    user_target=no
-    for arg
-    do
-      # Accept any command-line options.
-      case "$arg" in
-      -o)
-	if test "$user_target" != "no"; then
-	  $echo "$modename: you cannot specify \`-o' more than once" 1>&2
-	  exit 1
-	fi
-	user_target=next
-	;;
-
-      -static)
-	build_old_libs=yes
-	continue
-	;;
-      esac
-
-      case "$user_target" in
-      next)
-	# The next one is the -o target name
-	user_target=yes
-	continue
-	;;
-      yes)
-	# We got the output file
-	user_target=set
-	libobj="$arg"
-	continue
-	;;
-      esac
-
-      # Accept the current argument as the source file.
-      lastarg="$srcfile"
-      srcfile="$arg"
-
-      # Aesthetically quote the previous argument.
-
-      # Backslashify any backslashes, double quotes, and dollar signs.
-      # These are the only characters that are still specially
-      # interpreted inside of double-quoted scrings.
-      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
-
-      # Double-quote args containing other shell metacharacters.
-      # Many Bourne shells cannot handle close brackets correctly in scan
-      # sets, so we specify it separately.
-      case "$lastarg" in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
-	lastarg="\"$lastarg\""
-	;;
-      esac
-
-      # Add the previous argument to base_compile.
-      if test -z "$base_compile"; then
-	base_compile="$lastarg"
-      else
-	base_compile="$base_compile $lastarg"
-      fi
-    done
-
-    case "$user_target" in
-    set)
-      ;;
-    no)
-      # Get the name of the library object.
-      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
-      ;;
-    *)
-      $echo "$modename: you must specify a target with \`-o'" 1>&2
-      exit 1
-      ;;
-    esac
-
-    # Recognize several different file suffixes.
-    # If the user specifies -o file.o, it is replaced with file.lo
-    xform='[cCFSfmso]'
-    case "$libobj" in
-    *.ada) xform=ada ;;
-    *.adb) xform=adb ;;
-    *.ads) xform=ads ;;
-    *.asm) xform=asm ;;
-    *.c++) xform=c++ ;;
-    *.cc) xform=cc ;;
-    *.cpp) xform=cpp ;;
-    *.cxx) xform=cxx ;;
-    *.f90) xform=f90 ;;
-    *.for) xform=for ;;
-    esac
-
-    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
-
-    case "$libobj" in
-    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
-    *)
-      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
-      exit 1
-      ;;
-    esac
-
-    if test -z "$base_compile"; then
-      $echo "$modename: you must specify a compilation command" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    # Delete any leftover library objects.
-    if test "$build_old_libs" = yes; then
-      removelist="$obj $libobj"
-    else
-      removelist="$libobj"
-    fi
-
-    $run $rm $removelist
-    trap "$run $rm $removelist; exit 1" 1 2 15
-
-    # Calculate the filename of the output object if compiler does
-    # not support -o with -c
-    if test "$compiler_c_o" = no; then
-      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
-      lockfile="$output_obj.lock"
-      removelist="$removelist $output_obj $lockfile"
-      trap "$run $rm $removelist; exit 1" 1 2 15
-    else
-      need_locks=no
-      lockfile=
-    fi
-
-    # Lock this critical section if it is needed
-    # We use this script file to make the link, it avoids creating a new file
-    if test "$need_locks" = yes; then
-      until ln "$0" "$lockfile" 2>/dev/null; do
-	$show "Waiting for $lockfile to be removed"
-	sleep 2
-      done
-    elif test "$need_locks" = warn; then
-      if test -f "$lockfile"; then
-	echo "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-	$run $rm $removelist
-	exit 1
-      fi
-      echo $srcfile > "$lockfile"
-    fi
-
-    if test -n "$fix_srcfile_path"; then
-      eval srcfile=\"$fix_srcfile_path\"
-    fi
-
-    # Only build a PIC object if we are building libtool libraries.
-    if test "$build_libtool_libs" = yes; then
-      # Without this assignment, base_compile gets emptied.
-      fbsd_hideous_sh_bug=$base_compile
-
-      # All platforms use -DPIC, to notify preprocessed assembler code.
-      command="$base_compile $pic_flag -DPIC $srcfile"
-      if test "$build_old_libs" = yes; then
-	lo_libobj="$libobj"
-	dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
-	if test "X$dir" = "X$libobj"; then
-	  dir="$objdir"
-	else
-	  dir="$dir/$objdir"
-	fi
-	libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
-
-	if test -d "$dir"; then
-	  $show "$rm $libobj"
-	  $run $rm $libobj
-	else
-	  $show "$mkdir $dir"
-	  $run $mkdir $dir
-	  status=$?
-	  if test $status -ne 0 && test ! -d $dir; then
-	    exit $status
-	  fi
-	fi
-      fi
-      if test "$compiler_o_lo" = yes; then
-	output_obj="$libobj"
-	command="$command -o $output_obj"
-      elif test "$compiler_c_o" = yes; then
-	output_obj="$obj"
-	command="$command -o $output_obj"
-      fi
-
-      $show "$command"
-      if $run eval "$command"; then :
-      else
-	test -n "$output_obj" && $run $rm $removelist
-	exit 1
-      fi
-
-      if test "$need_locks" = warn &&
-	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
-	echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-	$run $rm $removelist
-	exit 1
-      fi
-
-      # Just move the object if needed, then go on to compile the next one
-      if test x"$output_obj" != x"$libobj"; then
-	$show "$mv $output_obj $libobj"
-	if $run $mv $output_obj $libobj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
-
-      # If we have no pic_flag, then copy the object into place and finish.
-      if test -z "$pic_flag" && test "$build_old_libs" = yes; then
-	# Rename the .lo from within objdir to obj
-	if test -f $obj; then
-	  $show $rm $obj
-	  $run $rm $obj
-	fi
-
-	$show "$mv $libobj $obj"
-	if $run $mv $libobj $obj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-
-	# Now arrange that obj and lo_libobj become the same file
-	$show "$LN_S $obj $lo_libobj"
-	if $run $LN_S $obj $lo_libobj; then
-	  exit 0
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
-
-      # Allow error messages only from the first compilation.
-      suppress_output=' >/dev/null 2>&1'
-    fi
-
-    # Only build a position-dependent object if we build old libraries.
-    if test "$build_old_libs" = yes; then
-      command="$base_compile $srcfile"
-      if test "$compiler_c_o" = yes; then
-	command="$command -o $obj"
-	output_obj="$obj"
-      fi
-
-      # Suppress compiler output if we already did a PIC compilation.
-      command="$command$suppress_output"
-      $show "$command"
-      if $run eval "$command"; then :
-      else
-	$run $rm $removelist
-	exit 1
-      fi
-
-      if test "$need_locks" = warn &&
-	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
-	echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
-	$run $rm $removelist
-	exit 1
-      fi
-
-      # Just move the object if needed
-      if test x"$output_obj" != x"$obj"; then
-	$show "$mv $output_obj $obj"
-	if $run $mv $output_obj $obj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
-
-      # Create an invalid libtool object if no PIC, so that we do not
-      # accidentally link it into a program.
-      if test "$build_libtool_libs" != yes; then
-	$show "echo timestamp > $libobj"
-	$run eval "echo timestamp > \$libobj" || exit $?
-      else
-	# Move the .lo from within objdir
-	$show "$mv $libobj $lo_libobj"
-	if $run $mv $libobj $lo_libobj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
-    fi
-
-    # Unlock the critical section if it was locked
-    if test "$need_locks" != no; then
-      $rm "$lockfile"
-    fi
-
-    exit 0
-    ;;
-
-  # libtool link mode
-  link)
-    modename="$modename: link"
-    C_compiler="$CC" # save it, to compile generated C sources
-    CC="$nonopt"
-    case "$host" in
-    *-*-cygwin* | *-*-mingw* | *-*-os2*)
-      # It is impossible to link a dll without this setting, and
-      # we shouldn't force the makefile maintainer to figure out
-      # which system we are compiling for in order to pass an extra
-      # flag for every libtool invokation.
-      # allow_undefined=no
-
-      # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll which has undefined symbols, in which case not
-      # even a static library is built.  For now, we need to specify
-      # -no-undefined on the libtool link line when we can be certain
-      # that all symbols are satisfied, otherwise we get a static library.
-      allow_undefined=yes
-
-      # This is a source program that is used to create dlls on Windows
-      # Don't remove nor modify the starting and closing comments
-# /* ltdll.c starts here */
-# #define WIN32_LEAN_AND_MEAN
-# #include <windows.h>
-# #undef WIN32_LEAN_AND_MEAN
-# #include <stdio.h>
-#
-# #ifdef __cplusplus
-# extern "C" {
-# #endif
-# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
-# #ifdef __cplusplus
-# }
-# #endif
-#
-# #include <cygwin/cygwin_dll.h>
-# DECLARE_CYGWIN_DLL( DllMain );
-# HINSTANCE __hDllInstance_base;
-#
-# BOOL APIENTRY
-# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
-# {
-#   __hDllInstance_base = hInst;
-#   return TRUE;
-# }
-# /* ltdll.c ends here */
-      # This is a source program that is used to create import libraries
-      # on Windows for dlls which lack them. Don't remove nor modify the
-      # starting and closing comments
-# /* impgen.c starts here */
-# /*   Copyright (C) 1999 Free Software Foundation, Inc.
-# 
-#  This file is part of GNU libtool.
-# 
-#  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.
-#  */
-# 
-#  #include <stdio.h>		/* for printf() */
-#  #include <unistd.h>		/* for open(), lseek(), read() */
-#  #include <fcntl.h>		/* for O_RDONLY, O_BINARY */
-#  #include <string.h>		/* for strdup() */
-# 
-#  static unsigned int
-#  pe_get16 (fd, offset)
-#       int fd;
-#       int offset;
-#  {
-#    unsigned char b[2];
-#    lseek (fd, offset, SEEK_SET);
-#    read (fd, b, 2);
-#    return b[0] + (b[1]<<8);
-#  }
-# 
-#  static unsigned int
-#  pe_get32 (fd, offset)
-#      int fd;
-#      int offset;
-#  {
-#    unsigned char b[4];
-#    lseek (fd, offset, SEEK_SET);
-#    read (fd, b, 4);
-#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
-#  }
-# 
-#  static unsigned int
-#  pe_as32 (ptr)
-#       void *ptr;
-#  {
-#    unsigned char *b = ptr;
-#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
-#  }
-# 
-#  int
-#  main (argc, argv)
-#      int argc;
-#      char *argv[];
-#  {
-#      int dll;
-#      unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
-#      unsigned long export_rva, export_size, nsections, secptr, expptr;
-#      unsigned long name_rvas, nexp;
-#      unsigned char *expdata, *erva;
-#      char *filename, *dll_name;
-# 
-#      filename = argv[1];
-# 
-#      dll = open(filename, O_RDONLY|O_BINARY);
-#      if (!dll)
-#  	return 1;
-# 
-#      dll_name = filename;
-#    
-#      for (i=0; filename[i]; i++)
-#  	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
-#  	    dll_name = filename + i +1;
-# 
-#      pe_header_offset = pe_get32 (dll, 0x3c);
-#      opthdr_ofs = pe_header_offset + 4 + 20;
-#      num_entries = pe_get32 (dll, opthdr_ofs + 92);
-# 
-#      if (num_entries < 1) /* no exports */
-#  	return 1;
-# 
-#      export_rva = pe_get32 (dll, opthdr_ofs + 96);
-#      export_size = pe_get32 (dll, opthdr_ofs + 100);
-#      nsections = pe_get16 (dll, pe_header_offset + 4 +2);
-#      secptr = (pe_header_offset + 4 + 20 +
-#  	      pe_get16 (dll, pe_header_offset + 4 + 16));
-# 
-#      expptr = 0;
-#      for (i = 0; i < nsections; i++)
-#      {
-#  	char sname[8];
-#  	unsigned long secptr1 = secptr + 40 * i;
-#  	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
-#  	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
-#  	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
-#  	lseek(dll, secptr1, SEEK_SET);
-#  	read(dll, sname, 8);
-#  	if (vaddr <= export_rva && vaddr+vsize > export_rva)
-#  	{
-#  	    expptr = fptr + (export_rva - vaddr);
-#  	    if (export_rva + export_size > vaddr + vsize)
-#  		export_size = vsize - (export_rva - vaddr);
-#  	    break;
-#  	}
-#      }
-# 
-#      expdata = (unsigned char*)malloc(export_size);
-#      lseek (dll, expptr, SEEK_SET);
-#      read (dll, expdata, export_size);
-#      erva = expdata - export_rva;
-# 
-#      nexp = pe_as32 (expdata+24);
-#      name_rvas = pe_as32 (expdata+32);
-# 
-#      printf ("EXPORTS\n");
-#      for (i = 0; i<nexp; i++)
-#      {
-#  	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
-#  	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
-#      }
-# 
-#      return 0;
-#  }
-# /* impgen.c ends here */
-      ;;
-    *)
-      allow_undefined=yes
-      ;;
-    esac
-    compile_command="$CC"
-    finalize_command="$CC"
-
-    compile_rpath=
-    finalize_rpath=
-    compile_shlibpath=
-    finalize_shlibpath=
-    convenience=
-    old_convenience=
-    deplibs=
-    linkopts=
-
-    if test -n "$shlibpath_var"; then
-      # get the directories listed in $shlibpath_var
-      eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
-    else
-      lib_search_path=
-    fi
-    # now prepend the system-specific ones
-    eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
-    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
-    
-    avoid_version=no
-    dlfiles=
-    dlprefiles=
-    dlself=no
-    export_dynamic=no
-    export_symbols=
-    export_symbols_regex=
-    generated=
-    libobjs=
-    link_against_libtool_libs=
-    ltlibs=
-    module=no
-    objs=
-    prefer_static_libs=no
-    preload=no
-    prev=
-    prevarg=
-    release=
-    rpath=
-    xrpath=
-    perm_rpath=
-    temp_rpath=
-    thread_safe=no
-    vinfo=
-
-    # We need to know -static, to get the right output filenames.
-    for arg
-    do
-      case "$arg" in
-      -all-static | -static)
-	if test "X$arg" = "X-all-static"; then
-	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
-	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
-	  fi
-	  if test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	else
-	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	fi
-	build_libtool_libs=no
-	build_old_libs=yes
-	prefer_static_libs=yes
-	break
-	;;
-      esac
-    done
-
-    # See if our shared archives depend on static archives.
-    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
-
-    # Go through the arguments, transforming them on the way.
-    while test $# -gt 0; do
-      arg="$1"
-      shift
-
-      # If the previous option needs an argument, assign it.
-      if test -n "$prev"; then
-	case "$prev" in
-	output)
-	  compile_command="$compile_command @OUTPUT@"
-	  finalize_command="$finalize_command @OUTPUT@"
-	  ;;
-	esac
-
-	case "$prev" in
-	dlfiles|dlprefiles)
-	  if test "$preload" = no; then
-	    # Add the symbol object into the linking commands.
-	    compile_command="$compile_command @SYMFILE@"
-	    finalize_command="$finalize_command @SYMFILE@"
-	    preload=yes
-	  fi
-	  case "$arg" in
-	  *.la | *.lo) ;;  # We handle these cases below.
-	  self)
-	    if test "$prev" = dlprefiles; then
-	      dlself=yes
-	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
-	      dlself=yes
-	    else
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  *)
-	    if test "$prev" = dlfiles; then
-	      dlfiles="$dlfiles $arg"
-	    else
-	      dlprefiles="$dlprefiles $arg"
-	    fi
-	    prev=
-	    ;;
-	  esac
-	  ;;
-	expsyms)
-	  export_symbols="$arg"
-	  if test ! -f "$arg"; then
-	    $echo "$modename: symbol file \`$arg' does not exist"
-	    exit 1
-	  fi
-	  prev=
-	  continue
-	  ;;
-	expsyms_regex)
-	  export_symbols_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	release)
-	  release="-$arg"
-	  prev=
-	  continue
-	  ;;
-	rpath | xrpath)
-	  # We need an absolute path.
-	  case "$arg" in
-	  [\\/]* | [A-Za-z]:[\\/]*) ;;
-	  *)
-	    $echo "$modename: only absolute run-paths are allowed" 1>&2
-	    exit 1
-	    ;;
-	  esac
-	  if test "$prev" = rpath; then
-	    case "$rpath " in
-	    *" $arg "*) ;;
-	    *) rpath="$rpath $arg" ;;
-	    esac
-	  else
-	    case "$xrpath " in
-	    *" $arg "*) ;;
-	    *) xrpath="$xrpath $arg" ;;
-	    esac
-	  fi
-	  prev=
-	  continue
-	  ;;
-	*)
-	  eval "$prev=\"\$arg\""
-	  prev=
-	  continue
-	  ;;
-	esac
-      fi
-
-      prevarg="$arg"
-
-      case "$arg" in
-      -all-static)
-	if test -n "$link_static_flag"; then
-	  compile_command="$compile_command $link_static_flag"
-	  finalize_command="$finalize_command $link_static_flag"
-	fi
-	continue
-	;;
-
-      -allow-undefined)
-	# FIXME: remove this flag sometime in the future.
-	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
-	continue
-	;;
-
-      -avoid-version)
-	avoid_version=yes
-	continue
-	;;
-
-      -dlopen)
-	prev=dlfiles
-	continue
-	;;
-
-      -dlpreopen)
-	prev=dlprefiles
-	continue
-	;;
-
-      -export-dynamic)
-	export_dynamic=yes
-	continue
-	;;
-
-      -export-symbols | -export-symbols-regex)
-	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	  $echo "$modename: not more than one -exported-symbols argument allowed"
-	  exit 1
-	fi
-	if test "X$arg" = "X-export-symbols"; then
-	  prev=expsyms
-	else
-	  prev=expsyms_regex
-	fi
-	continue
-	;;
-
-      -L*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
-	# We need an absolute path.
-	case "$dir" in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  absdir=`cd "$dir" && pwd`
-	  if test -z "$absdir"; then
-	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-	    exit 1
-	  fi
-	  dir="$absdir"
-	  ;;
-	esac
-	case " $deplibs " in
-	*" $arg "*) ;;
-	*) deplibs="$deplibs $arg";;
-	esac
-	case " $lib_search_path " in
-	*" $dir "*) ;;
-	*) lib_search_path="$lib_search_path $dir";;
-	esac
-	case "$host" in
-	*-*-cygwin* | *-*-mingw* | *-*-os2*)
-	  dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
-	  case ":$dllsearchpath:" in
-	  ::) dllsearchpath="$dllsearchdir";;
-	  *":$dllsearchdir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
-	  esac
-	  ;;
-	esac
-	;;
-
-      -l*)
-	if test "$arg" = "-lc"; then
-	  case "$host" in
-	  *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
-	    # These systems don't actually have c library (as such)
-	    continue
-	    ;;
-	  esac
-	elif test "$arg" = "-lm"; then
-	  case "$host" in
-	  *-*-cygwin* | *-*-beos*)
-	    # These systems don't actually have math library (as such)
-	    continue
-	    ;;
-	  esac
-	fi
-	deplibs="$deplibs $arg"
-	;;
-
-      -module)
-	module=yes
-	continue
-	;;
-
-      -no-undefined)
-	allow_undefined=no
-	continue
-	;;
-
-      -o) prev=output ;;
-
-      -release)
-	prev=release
-	continue
-	;;
-
-      -rpath)
-	prev=rpath
-	continue
-	;;
-
-      -R)
-	prev=xrpath
-	continue
-	;;
-
-      -R*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
-	# We need an absolute path.
-	case "$dir" in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  $echo "$modename: only absolute run-paths are allowed" 1>&2
-	  exit 1
-	  ;;
-	esac
-	case "$xrpath " in
-	*" $dir "*) ;;
-	*) xrpath="$xrpath $dir" ;;
-	esac
-	continue
-	;;
-
-      -static)
-	# If we have no pic_flag, then this is the same as -all-static.
-	if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	  compile_command="$compile_command $link_static_flag"
-	  finalize_command="$finalize_command $link_static_flag"
-	fi
-	continue
-	;;
-
-      -thread-safe)
-	thread_safe=yes
-	continue
-	;;
-
-      -version-info)
-	prev=vinfo
-	continue
-	;;
-
-      # Some other compiler flag.
-      -* | +*)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case "$arg" in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
-
-      *.o | *.obj | *.a | *.lib)
-	# A standard object.
-	objs="$objs $arg"
-	;;
-
-      *.lo)
-	# A library object.
-	if test "$prev" = dlfiles; then
-	  dlfiles="$dlfiles $arg"
-	  if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
-	    prev=
-	    continue
-	  else
-	    # If libtool objects are unsupported, then we need to preload.
-	    prev=dlprefiles
-	  fi
-	fi
-
-	if test "$prev" = dlprefiles; then
-	  # Preload the old-style object.
-	  dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
-	  prev=
-	fi
-	libobjs="$libobjs $arg"
-	;;
-
-      *.la)
-	# A libtool-controlled library.
-
-	dlname=
-	libdir=
-	library_names=
-	old_library=
-
-	# Check to see that this really is a libtool archive.
-	if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
-	  exit 1
-	fi
-
-	# If the library was installed with an old release of libtool,
-	# it will not redefine variable installed.
-	installed=yes
-
-	# Read the .la file
-	# If there is no directory component, then add one.
-	case "$arg" in
-	*/* | *\\*) . $arg ;;
-	*) . ./$arg ;;
-	esac
-
-	# Get the name of the library we link against.
-	linklib=
-	for l in $old_library $library_names; do
-	  linklib="$l"
-	done
-
-	if test -z "$linklib"; then
-	  $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
-	  exit 1
-	fi
-
-	# Find the relevant object directory and library name.
-	name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
-
-	if test "X$installed" = Xyes; then
-	  dir="$libdir"
-	else
-	  dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	  if test "X$dir" = "X$arg"; then
-	    dir="$objdir"
-	  else
-	    dir="$dir/$objdir"
-	  fi
-	fi
-
-	if test -n "$dependency_libs"; then
-	  # Extract -R from dependency_libs
-	  temp_deplibs=
-	  for deplib in $dependency_libs; do
-	    case "$deplib" in
-	    -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
-		 case " $rpath $xrpath " in
-		 *" $temp_xrpath "*) ;;
-		 *) xrpath="$xrpath $temp_xrpath";;
-		 esac;;
-	    -L*) case "$compile_command $temp_deplibs " in
-		 *" $deplib "*) ;;
-		 *) temp_deplibs="$temp_deplibs $deplib";;
-		 esac;;
-	    *) temp_deplibs="$temp_deplibs $deplib";;
-	    esac
-	  done
-	  dependency_libs="$temp_deplibs"
-	fi
-
-	if test -z "$libdir"; then
-	  # It is a libtool convenience library, so add in its objects.
-	  convenience="$convenience $dir/$old_library"
-	  old_convenience="$old_convenience $dir/$old_library"
-	  deplibs="$deplibs$dependency_libs"
-	  compile_command="$compile_command $dir/$old_library$dependency_libs"
-	  finalize_command="$finalize_command $dir/$old_library$dependency_libs"
-	  continue
-	fi
-
-	# This library was specified with -dlopen.
-	if test "$prev" = dlfiles; then
-	  dlfiles="$dlfiles $arg"
-	  if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
-	    # If there is no dlname, no dlopen support or we're linking statically,
-	    # we need to preload.
-	    prev=dlprefiles
-	  else
-	    # We should not create a dependency on this library, but we
-	    # may need any libraries it requires.
-	    compile_command="$compile_command$dependency_libs"
-	    finalize_command="$finalize_command$dependency_libs"
-	    prev=
-	    continue
-	  fi
-	fi
-
-	# The library was specified with -dlpreopen.
-	if test "$prev" = dlprefiles; then
-	  # Prefer using a static library (so that no silly _DYNAMIC symbols
-	  # are required to link).
-	  if test -n "$old_library"; then
-	    dlprefiles="$dlprefiles $dir/$old_library"
-	  else
-	    dlprefiles="$dlprefiles $dir/$linklib"
-	  fi
-	  prev=
-	fi
-
-	if test -n "$library_names" &&
-	   { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
-	  link_against_libtool_libs="$link_against_libtool_libs $arg"
-	  if test -n "$shlibpath_var"; then
-	    # Make sure the rpath contains only unique directories.
-	    case "$temp_rpath " in
-	    *" $dir "*) ;;
-	    *) temp_rpath="$temp_rpath $dir" ;;
-	    esac
-	  fi
-
-	  # We need an absolute path.
-	  case "$dir" in
-	  [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
-	  *)
-	    absdir=`cd "$dir" && pwd`
-	    if test -z "$absdir"; then
-	      $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-	      exit 1
-	    fi
-	    ;;
-	  esac
-	  
-	  # This is the magic to use -rpath.
-	  # Skip directories that are in the system default run-time
-	  # search path, unless they have been requested with -R.
-	  case " $sys_lib_dlsearch_path " in
-	  *" $absdir "*) ;;
-	  *)
-	    case "$compile_rpath " in
-	    *" $absdir "*) ;;
-	    *) compile_rpath="$compile_rpath $absdir" 
-	    esac
-	    ;;
-	  esac
-
-	  case " $sys_lib_dlsearch_path " in
-	  *" $libdir "*) ;;
-	  *)
-	    case "$finalize_rpath " in
-	    *" $libdir "*) ;;
-	    *) finalize_rpath="$finalize_rpath $libdir"
-	    esac
-	    ;;
-	  esac
-
-	  lib_linked=yes
-	  case "$hardcode_action" in
-	  immediate | unsupported)
-	    if test "$hardcode_direct" = no; then
-	      compile_command="$compile_command $dir/$linklib"
-	      deplibs="$deplibs $dir/$linklib"
-	      case "$host" in
-	      *-*-cygwin* | *-*-mingw* | *-*-os2*)
-		dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
-		if test -n "$dllsearchpath"; then
-		  dllsearchpath="$dllsearchpath:$dllsearchdir"
-		else
-		  dllsearchpath="$dllsearchdir"
-		fi
-		;;
-	      esac
-	    elif test "$hardcode_minus_L" = no; then
-	      case "$host" in
-	      *-*-sunos*)
-		compile_shlibpath="$compile_shlibpath$dir:"
-		;;
-	      esac
-	      case "$compile_command " in
-	      *" -L$dir "*) ;;
-	      *) compile_command="$compile_command -L$dir";;
-	      esac
-	      compile_command="$compile_command -l$name"
-	      deplibs="$deplibs -L$dir -l$name"
-	    elif test "$hardcode_shlibpath_var" = no; then
-	      case ":$compile_shlibpath:" in
-	      *":$dir:"*) ;;
-	      *) compile_shlibpath="$compile_shlibpath$dir:";;
-	      esac
-	      compile_command="$compile_command -l$name"
-	      deplibs="$deplibs -l$name"
-	    else
-	      lib_linked=no
-	    fi
-	    ;;
-
-	  relink)
-	    if test "$hardcode_direct" = yes; then
-	      compile_command="$compile_command $absdir/$linklib"
-	      deplibs="$deplibs $absdir/$linklib"
-	    elif test "$hardcode_minus_L" = yes; then
-	      case "$compile_command " in
-	      *" -L$absdir "*) ;;
-	      *) compile_command="$compile_command -L$absdir";;
-	      esac
-	      compile_command="$compile_command -l$name"
-	      deplibs="$deplibs -L$absdir -l$name"
-	    elif test "$hardcode_shlibpath_var" = yes; then
-	      case ":$compile_shlibpath:" in
-	      *":$absdir:"*) ;;
-	      *) compile_shlibpath="$compile_shlibpath$absdir:";;
-	      esac
-	      compile_command="$compile_command -l$name"
-	      deplibs="$deplibs -l$name"
-	    else
-	      lib_linked=no
-	    fi
-	    ;;
-
-	  *)
-	    lib_linked=no
-	    ;;
-	  esac
-
-	  if test "$lib_linked" != yes; then
-	    $echo "$modename: configuration error: unsupported hardcode properties"
-	    exit 1
-	  fi
-
-	  # Finalize command for both is simple: just hardcode it.
-	  if test "$hardcode_direct" = yes; then
-	    finalize_command="$finalize_command $libdir/$linklib"
-	  elif test "$hardcode_minus_L" = yes; then
-	    case "$finalize_command " in
-	    *" -L$libdir "*) ;;
-	    *) finalize_command="$finalize_command -L$libdir";;
-	    esac
-	    finalize_command="$finalize_command -l$name"
-	  elif test "$hardcode_shlibpath_var" = yes; then
-	    case ":$finalize_shlibpath:" in
-	    *":$libdir:"*) ;;
-	    *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
-	    esac
-	    finalize_command="$finalize_command -l$name"
-	  else
-	    # We cannot seem to hardcode it, guess we'll fake it.
-	    case "$finalize_command " in
-	    *" -L$dir "*) ;;
-	    *) finalize_command="$finalize_command -L$libdir";;
-	    esac
-	    finalize_command="$finalize_command -l$name"
-	  fi
-	else
-	  # Transform directly to old archives if we don't build new libraries.
-	  if test -n "$pic_flag" && test -z "$old_library"; then
-	    $echo "$modename: cannot find static library for \`$arg'" 1>&2
-	    exit 1
-	  fi
-
-	  # Here we assume that one of hardcode_direct or hardcode_minus_L
-	  # is not unsupported.  This is valid on all known static and
-	  # shared platforms.
-	  if test "$hardcode_direct" != unsupported; then
-	    test -n "$old_library" && linklib="$old_library"
-	    compile_command="$compile_command $dir/$linklib"
-	    finalize_command="$finalize_command $dir/$linklib"
-	  else
-	    case "$compile_command " in
-	    *" -L$dir "*) ;;
-	    *) compile_command="$compile_command -L$dir";;
-	    esac
-	    compile_command="$compile_command -l$name"
-	    case "$finalize_command " in
-	    *" -L$dir "*) ;;
-	    *) finalize_command="$finalize_command -L$dir";;
-	    esac
-	    finalize_command="$finalize_command -l$name"
-	  fi
-	fi
-
-	# Add in any libraries that this one depends upon.
-	compile_command="$compile_command$dependency_libs"
-	finalize_command="$finalize_command$dependency_libs"
-	continue
-	;;
-
-      # Some other compiler argument.
-      *)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case "$arg" in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
-      esac
-
-      # Now actually substitute the argument into the commands.
-      if test -n "$arg"; then
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-      fi
-    done
-
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
-      eval arg=\"$export_dynamic_flag_spec\"
-      compile_command="$compile_command $arg"
-      finalize_command="$finalize_command $arg"
-    fi
-
-    oldlibs=
-    # calculate the name of the file, without its directory
-    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
-    libobjs_save="$libobjs"
-
-    case "$output" in
-    "")
-      $echo "$modename: you must specify an output file" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-      ;;
-
-    *.a | *.lib)
-      if test -n "$link_against_libtool_libs"; then
-	$echo "$modename: error: cannot link libtool libraries into archives" 1>&2
-	exit 1
-      fi
-
-      if test -n "$deplibs"; then
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
-      fi
-
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
-      fi
-
-      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
-      fi
-
-      # Now set the variables for building old libraries.
-      build_libtool_libs=no
-      oldlibs="$output"
-      ;;
-
-    *.la)
-      # Make sure we only generate libraries of the form `libNAME.la'.
-      case "$outputname" in
-      lib*)
-	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-	eval libname=\"$libname_spec\"
-	;;
-      *)
-	if test "$module" = no; then
-	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
-	  $echo "$help" 1>&2
-	  exit 1
-	fi
-	if test "$need_lib_prefix" != no; then
-	  # Add the "lib" prefix for modules if required
-	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	  eval libname=\"$libname_spec\"
-	else
-	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	fi
-	;;
-      esac
-
-      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
-      if test "X$output_objdir" = "X$output"; then
-	output_objdir="$objdir"
-      else
-	output_objdir="$output_objdir/$objdir"
-      fi
-
-      if test -n "$objs"; then
-	$echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
-	exit 1
-      fi
-
-      # How the heck are we supposed to write a wrapper for a shared library?
-      if test -n "$link_against_libtool_libs"; then
-	 $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
-	 exit 1
-      fi
-
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
-      fi
-
-      set dummy $rpath
-      if test $# -gt 2; then
-	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
-      fi
-      install_libdir="$2"
-
-      oldlibs=
-      if test -z "$rpath"; then
-	if test "$build_libtool_libs" = yes; then
-	  # Building a libtool convenience library.
-	  libext=al
-	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
-	  build_libtool_libs=convenience
-	  build_old_libs=yes
-	fi
-	dependency_libs="$deplibs"
-
-	if test -n "$vinfo"; then
-	  $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
-	fi
-
-	if test -n "$release"; then
-	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
-	fi
-      else
-
-	# Parse the version information argument.
-	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=':'
-	set dummy $vinfo 0 0 0
-	IFS="$save_ifs"
-
-	if test -n "$8"; then
-	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
-	  $echo "$help" 1>&2
-	  exit 1
-	fi
-
-	current="$2"
-	revision="$3"
-	age="$4"
-
-	# Check that each of the things are valid numbers.
-	case "$current" in
-	0 | [1-9] | [1-9][0-9]*) ;;
-	*)
-	  $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit 1
-	  ;;
-	esac
-
-	case "$revision" in
-	0 | [1-9] | [1-9][0-9]*) ;;
-	*)
-	  $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit 1
-	  ;;
-	esac
-
-	case "$age" in
-	0 | [1-9] | [1-9][0-9]*) ;;
-	*)
-	  $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit 1
-	  ;;
-	esac
-
-	if test $age -gt $current; then
-	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit 1
-	fi
-
-	# Calculate the version variables.
-	major=
-	versuffix=
-	verstring=
-	case "$version_type" in
-	none) ;;
-
-	irix)
-	  major=`expr $current - $age + 1`
-	  versuffix="$major.$revision"
-	  verstring="sgi$major.$revision"
-
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$revision
-	  while test $loop != 0; do
-	    iface=`expr $revision - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="sgi$major.$iface:$verstring"
-	  done
-	  ;;
-
-	linux)
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  ;;
-
-	osf)
-	  major=`expr $current - $age`
-	  versuffix=".$current.$age.$revision"
-	  verstring="$current.$age.$revision"
-
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$age
-	  while test $loop != 0; do
-	    iface=`expr $current - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring:${iface}.0"
-	  done
-
-	  # Make executables depend on our current version.
-	  verstring="$verstring:${current}.0"
-	  ;;
-
-	sunos)
-	  major=".$current"
-	  versuffix=".$current.$revision"
-	  ;;
-
-	freebsd-aout)
-	  major=".$current"
-	  versuffix=".$current.$revision";
-	  ;;
-
-	freebsd-elf)
-	  major=".$current"
-	  versuffix=".$current";
-	  ;;
-
-	windows)
-	  # Like Linux, but with '-' rather than '.', since we only
-	  # want one extension on Windows 95.
-	  major=`expr $current - $age`
-	  versuffix="-$major-$age-$revision"
-	  ;;
-
-	*)
-	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
-	  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-	  exit 1
-	  ;;
-	esac
-
-	# Clear the version info if we defaulted, and they specified a release.
-	if test -z "$vinfo" && test -n "$release"; then
-	  major=
-	  verstring="0.0"
-	  if test "$need_version" = no; then
-	    versuffix=
-	  else
-	    versuffix=".0.0"
-	  fi
-	fi
-
-	# Remove version info from name if versioning should be avoided
-	if test "$avoid_version" = yes && test "$need_version" = no; then
-	  major=
-	  versuffix=
-	  verstring=""
-	fi
-	
-	# Check to see if the archive will have undefined symbols.
-	if test "$allow_undefined" = yes; then
-	  if test "$allow_undefined_flag" = unsupported; then
-	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
-	    build_libtool_libs=no
-	    build_old_libs=yes
-	  fi
-	else
-	  # Don't allow undefined symbols.
-	  allow_undefined_flag="$no_undefined_flag"
-	fi
-
-	dependency_libs="$deplibs"
-	case "$host" in
-	*-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
-	  # these systems don't actually have a c library (as such)!
-	  ;;
-	*)
-	  # Add libc to deplibs on all other systems.
-	  deplibs="$deplibs -lc"
-	  ;;
-	esac
-      fi
-
-      # Create the output directory, or remove our outputs if we need to.
-      if test -d $output_objdir; then
-	$show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
-	$run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
-      else
-	$show "$mkdir $output_objdir"
-	$run $mkdir $output_objdir
-	status=$?
-	if test $status -ne 0 && test ! -d $output_objdir; then
-	  exit $status
-	fi
-      fi
-
-      # Now set the variables for building old libraries.
-      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
-	oldlibs="$oldlibs $output_objdir/$libname.$libext"
-
-	# Transform .lo files to .o files.
-	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
-      fi
-
-      if test "$build_libtool_libs" = yes; then
-	# Transform deplibs into only deplibs that can be linked in shared.
-	name_save=$name
-	libname_save=$libname
-	release_save=$release
-	versuffix_save=$versuffix
-	major_save=$major
-	# I'm not sure if I'm treating the release correctly.  I think
-	# release should show up in the -l (ie -lgmp5) so we don't want to
-	# add it in twice.  Is that correct?
-	release=""
-	versuffix=""
-	major=""
-	newdeplibs=
-	droppeddeps=no
-	case "$deplibs_check_method" in
-	pass_all)
-	  # Don't check for shared/static.  Everything works.
-	  # This might be a little naive.  We might want to check
-	  # whether the library exists or not.  But this is on
-	  # osf3 & osf4 and I'm not really sure... Just
-	  # implementing what was already the behaviour.
-	  newdeplibs=$deplibs
-	  ;;
-	test_compile)
-	  # This code stresses the "libraries are programs" paradigm to its
-	  # limits. Maybe even breaks it.  We compile a program, linking it
-	  # against the deplibs as a proxy for the library.  Then we can check
-	  # whether they linked in statically or dynamically with ldd.
-	  $rm conftest.c
-	  cat > conftest.c <<EOF
-	  int main() { return 0; }
-EOF
-	  $rm conftest
-	  $C_compiler -o conftest conftest.c $deplibs
-	  if test $? -eq 0 ; then
-	    ldd_output=`ldd conftest`
-	    for i in $deplibs; do
-	      name="`expr $i : '-l\(.*\)'`"
-	      # If $name is empty we are operating on a -L argument.
-	      if test "$name" != "" ; then
-		libname=`eval \\$echo \"$libname_spec\"`
-		deplib_matches=`eval \\$echo \"$library_names_spec\"`
-		set dummy $deplib_matches
-		deplib_match=$2
-		if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-		  newdeplibs="$newdeplibs $i"
-		else
-		  droppeddeps=yes
-		  echo
-		  echo "*** Warning: This library needs some functionality provided by $i."
-		  echo "*** I have the capability to make that library automatically link in when"
-		  echo "*** you link to this library.  But I can only do this if you have a"
-		  echo "*** shared version of the library, which you do not appear to have."
-		fi
-	      else
-		newdeplibs="$newdeplibs $i"
-	      fi
-	    done
-	  else
-	    # Error occured in the first compile.  Let's try to salvage the situation:
-	    # Compile a seperate program for each library.
-	    for i in $deplibs; do
-	      name="`expr $i : '-l\(.*\)'`"
-	     # If $name is empty we are operating on a -L argument.
-	      if test "$name" != "" ; then
-		$rm conftest
-		$C_compiler -o conftest conftest.c $i
-		# Did it work?
-		if test $? -eq 0 ; then
-		  ldd_output=`ldd conftest`
-		  libname=`eval \\$echo \"$libname_spec\"`
-		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
-		  set dummy $deplib_matches
-		  deplib_match=$2
-		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-		    newdeplibs="$newdeplibs $i"
-		  else
-		    droppeddeps=yes
-		    echo
-		    echo "*** Warning: This library needs some functionality provided by $i."
-		    echo "*** I have the capability to make that library automatically link in when"
-		    echo "*** you link to this library.  But I can only do this if you have a"
-		    echo "*** shared version of the library, which you do not appear to have."
-		  fi
-		else
-		  droppeddeps=yes
-		  echo
-		  echo "*** Warning!  Library $i is needed by this library but I was not able to"
-		  echo "***  make it link in!  You will probably need to install it or some"
-		  echo "*** library that it depends on before this library will be fully"
-		  echo "*** functional.  Installing it before continuing would be even better."
-		fi
-	      else
-		newdeplibs="$newdeplibs $i"
-	      fi
-	    done
-	  fi
-	  ;;
-	file_magic*)
-	  set dummy $deplibs_check_method
-	  file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
-	  for a_deplib in $deplibs; do
-	    name="`expr $a_deplib : '-l\(.*\)'`"
-	    # If $name is empty we are operating on a -L argument.
-	    if test "$name" != "" ; then
-	      libname=`eval \\$echo \"$libname_spec\"`
-	      for i in $lib_search_path; do
-		    potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-		    for potent_lib in $potential_libs; do
-		      # Follow soft links.
-		      if ls -lLd "$potlib" 2>/dev/null \
-			 | grep " -> " >/dev/null; then
-			continue 
-		      fi
-		      # The statement above tries to avoid entering an
-		      # endless loop below, in case of cyclic links.
-		      # We might still enter an endless loop, since a link
-		      # loop can be closed while we follow links,
-		      # but so what?
-		      potlib="$potent_lib"
-		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | sed 's/.* -> //'`
-			case "$potliblink" in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
-			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
-			esac
-		      done
-		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
-			 | sed 10q \
-			 | egrep "$file_magic_regex" > /dev/null; then
-			newdeplibs="$newdeplibs $a_deplib"
-			a_deplib=""
-			break 2
-		      fi
-		    done
-	      done
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		echo
-		echo "*** Warning: This library needs some functionality provided by $a_deplib."
-		echo "*** I have the capability to make that library automatically link in when"
-		echo "*** you link to this library.  But I can only do this if you have a"
-		echo "*** shared version of the library, which you do not appear to have."
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	none | unknown | *)
-	  newdeplibs=""
-	  if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
-	       -e 's/ -[LR][^ ]*//g' -e 's/[ 	]//g' |
-	     grep . >/dev/null; then
-	    echo
-	    if test "X$deplibs_check_method" = "Xnone"; then
-	      echo "*** Warning: inter-library dependencies are not supported in this platform."
-	    else
-	      echo "*** Warning: inter-library dependencies are not known to be supported."
-	    fi
-	    echo "*** All declared inter-library dependencies are being dropped."
-	    droppeddeps=yes
-	  fi
-	  ;;
-	esac
-	versuffix=$versuffix_save
-	major=$major_save
-	release=$release_save
-	libname=$libname_save
-	name=$name_save
-
-	if test "$droppeddeps" = yes; then
-	  if test "$module" = yes; then
-	    echo
-	    echo "*** Warning: libtool could not satisfy all declared inter-library"
-	    echo "*** dependencies of module $libname.  Therefore, libtool will create"
-	    echo "*** a static module, that should work as long as the dlopening"
-	    echo "*** application is linked with the -dlopen flag."
-	    if test -z "$global_symbol_pipe"; then
-	      echo
-	      echo "*** However, this would only work if libtool was able to extract symbol"
-	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-	      echo "*** not find such a program.  So, this module is probably useless."
-	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	    fi
-	    if test "$build_old_libs" = no; then
-	      oldlibs="$output_objdir/$libname.$libext"
-	      build_libtool_libs=module
-	      build_old_libs=yes
-	    else
-	      build_libtool_libs=no
-	    fi
-	  else
-	    echo "*** The inter-library dependencies that have been dropped here will be"
-	    echo "*** automatically added whenever a program is linked with this library"
-	    echo "*** or is declared to -dlopen it."
-	  fi
-	fi
-	# Done checking deplibs!
-	deplibs=$newdeplibs
-      fi
-
-      # All the library-specific variables (install_libdir is set above).
-      library_names=
-      old_library=
-      dlname=
-      
-      # Test again, we may have decided not to build it any more
-      if test "$build_libtool_libs" = yes; then
-	# Get the real and link names of the library.
-	eval library_names=\"$library_names_spec\"
-	set dummy $library_names
-	realname="$2"
-	shift; shift
-
-	if test -n "$soname_spec"; then
-	  eval soname=\"$soname_spec\"
-	else
-	  soname="$realname"
-	fi
-
-	lib="$output_objdir/$realname"
-	for link
-	do
-	  linknames="$linknames $link"
-	done
-
-	# Ensure that we have .o objects for linkers which dislike .lo
-	# (e.g. aix) incase we are running --disable-static
-	for obj in $libobjs; do
-	  oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"`
-	  if test ! -f $oldobj; then
-	    $show "${LN_S} $obj $oldobj"
-	    $run ${LN_S} $obj $oldobj || exit $?
-	  fi
-	done
-
-	# Use standard objects if they are pic
-	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-
-	if test -n "$whole_archive_flag_spec"; then
-	  if test -n "$convenience"; then
-	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-	  fi
-	else
-	  gentop="$output_objdir/${outputname}x"
-	  $show "${rm}r $gentop"
-	  $run ${rm}r "$gentop"
-	  $show "mkdir $gentop"
-	  $run mkdir "$gentop"
-	  status=$?
-	  if test $status -ne 0 && test ! -d "$gentop"; then
-	    exit $status
-	  fi
-	  generated="$generated $gentop"
-	  
-	  for xlib in $convenience; do
-	    # Extract the objects.
-	    case "$xlib" in
-	    [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
-	    *) xabs=`pwd`"/$xlib" ;;
-	    esac
-	    xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
-	    xdir="$gentop/$xlib"
-
-	    $show "${rm}r $xdir"
-	    $run ${rm}r "$xdir"
-	    $show "mkdir $xdir"
-	    $run mkdir "$xdir"
-	    status=$?
-	    if test $status -ne 0 && test ! -d "$xdir"; then
-	      exit $status
-	    fi
-	    $show "(cd $xdir && $AR x $xabs)"
-	    $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
-
-	    libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
-	  done
-	fi
-
-	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
-	  eval flag=\"$thread_safe_flag_spec\"
-	  linkopts="$linkopts $flag"
-	fi
-
-	# Prepare the list of exported symbols
-	if test -z "$export_symbols"; then
-	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    eval cmds=\"$export_symbols_cmds\"
-	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	    for cmd in $cmds; do
-	      IFS="$save_ifs"
-	      $show "$cmd"
-	      $run eval "$cmd" || exit $?
-	    done
-	    IFS="$save_ifs"
-	    if test -n "$export_symbols_regex"; then
-	      $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
-	      $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
-	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
-	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
-	    fi
-	  fi
-	fi
-
-	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
-	fi
-
-	# Do each of the archive commands.
-	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-	  eval cmds=\"$archive_expsym_cmds\"
-	else
-	  eval cmds=\"$archive_cmds\"
-	fi
-	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  $show "$cmd"
-	  $run eval "$cmd" || exit $?
-	done
-	IFS="$save_ifs"
-
-	# Create links to the real library.
-	for linkname in $linknames; do
-	  if test "$realname" != "$linkname"; then
-	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
-	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
-	  fi
-	done
-
-	# If -module or -export-dynamic was specified, set the dlname.
-	if test "$module" = yes || test "$export_dynamic" = yes; then
-	  # On all known operating systems, these are identical.
-	  dlname="$soname"
-	fi
-      fi
-      ;;
-
-    *.lo | *.o | *.obj)
-      if test -n "$link_against_libtool_libs"; then
-	$echo "$modename: error: cannot link libtool libraries into objects" 1>&2
-	exit 1
-      fi
-
-      if test -n "$deplibs"; then
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
-      fi
-
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
-      fi
-
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
-      fi
-
-      case "$output" in
-      *.lo)
-	if test -n "$objs"; then
-	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
-	  exit 1
-	fi
-	libobj="$output"
-	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
-	;;
-      *)
-	libobj=
-	obj="$output"
-	;;
-      esac
-
-      # Delete the old objects.
-      $run $rm $obj $libobj
-
-      # Create the old-style object.
-      reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
-
-      output="$obj"
-      eval cmds=\"$reload_cmds\"
-      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-
-      # Exit if we aren't doing a library object file.
-      test -z "$libobj" && exit 0
-
-      if test "$build_libtool_libs" != yes; then
-	# Create an invalid libtool object if no PIC, so that we don't
-	# accidentally link it into a program.
-	$show "echo timestamp > $libobj"
-	$run eval "echo timestamp > $libobj" || exit $?
-	exit 0
-      fi
-
-      if test -n "$pic_flag"; then
-	# Only do commands if we really have different PIC objects.
-	reload_objs="$libobjs"
-	output="$libobj"
-	eval cmds=\"$reload_cmds\"
-	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  $show "$cmd"
-	  $run eval "$cmd" || exit $?
-	done
-	IFS="$save_ifs"
-      else
-	# Just create a symlink.
-	$show $rm $libobj
-	$run $rm $libobj
-	$show "$LN_S $obj $libobj"
-	$run $LN_S $obj $libobj || exit $?
-      fi
-
-      exit 0
-      ;;
-
-    # Anything else should be a program.
-    *)
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
-      fi
-
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
-      fi
-
-      if test "$preload" = yes; then
-	if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
-	   test "$dlopen_self_static" = unknown; then
-	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
-	fi 
-      fi
-    
-      if test -n "$rpath$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	for libdir in $rpath $xrpath; do
-	  # This is the magic to use -rpath.
-	  case "$compile_rpath " in
-	  *" $libdir "*) ;;
-	  *) compile_rpath="$compile_rpath $libdir" ;;
-	  esac
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-      fi
-
-      # Now hardcode the library paths
-      rpath=
-      hardcode_libdirs=
-      for libdir in $compile_rpath $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) perm_rpath="$perm_rpath $libdir" ;;
-	  esac
-	fi
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      compile_rpath="$rpath"
-
-      rpath=
-      hardcode_libdirs=
-      for libdir in $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$finalize_perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
-	  esac
-	fi
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      finalize_rpath="$rpath"
-
-      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
-      if test "X$output_objdir" = "X$output"; then
-	output_objdir="$objdir"
-      else
-	output_objdir="$output_objdir/$objdir"
-      fi
-
-      # Create the binary in the object directory, then wrap it.
-      if test ! -d $output_objdir; then
-	$show "$mkdir $output_objdir"
-	$run $mkdir $output_objdir
-	status=$?
-	if test $status -ne 0 && test ! -d $output_objdir; then
-	  exit $status
-	fi
-      fi
-
-      if test -n "$libobjs" && test "$build_old_libs" = yes; then
-	# Transform all the library objects into standard objects.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-      fi
-
-      dlsyms=
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" = yes; then
-	if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	  dlsyms="${outputname}S.c"
-	else
-	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
-	fi
-      fi
-
-      if test -n "$dlsyms"; then
-	case "$dlsyms" in
-	"") ;;
-	*.c)
-	  # Discover the nlist of each of the dlfiles.
-	  nlist="$output_objdir/${outputname}.nm"
-
-	  $show "$rm $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
-
-	  # Parse the name list into a source file.
-	  $show "creating $output_objdir/$dlsyms"
-
-	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
-
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
-
-/* External symbol declarations for the compiler. */\
-"
-
-	  if test "$dlself" = yes; then
-	    $show "generating symbol list for \`$output'"
-
-	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
-
-	    # Add our own program objects to the symbol list.
-	    progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	    for arg in $progfiles; do
-	      $show "extracting global C symbols from \`$arg'"
-	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	    done
-
-	    if test -n "$exclude_expsyms"; then
-	      $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
-	    
-	    if test -n "$export_symbols_regex"; then
-	      $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
-
-	    # Prepare the list of exported symbols
-	    if test -z "$export_symbols"; then
-	      export_symbols="$output_objdir/$output.exp"
-	      $run $rm $export_symbols
-	      $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
-	    else
-	      $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
-	      $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
-	      $run eval 'mv "$nlist"T "$nlist"'
-	    fi
-	  fi
-
-	  for arg in $dlprefiles; do
-	    $show "extracting global C symbols from \`$arg'"
-	    name=`echo "$arg" | sed -e 's%^.*/%%'`
-	    $run eval 'echo ": $name " >> "$nlist"'
-	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	  done
-
-	  if test -z "$run"; then
-	    # Make sure we have at least an empty file.
-	    test -f "$nlist" || : > "$nlist"
-
-	    if test -n "$exclude_expsyms"; then
-	      egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
-	      $mv "$nlist"T "$nlist"
-	    fi
-
-	    # Try sorting and uniquifying the output.
-	    if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
-	      :
-	    else
-	      grep -v "^: " < "$nlist" > "$nlist"S
-	    fi
-
-	    if test -f "$nlist"S; then
-	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
-	    else
-	      echo '/* NONE */' >> "$output_objdir/$dlsyms"
-	    fi
-
-	    $echo >> "$output_objdir/$dlsyms" "\
-
-#undef lt_preloaded_symbols
-
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
-  const char *name;
-  lt_ptr_t address;
-}
-lt_preloaded_symbols[] =
-{\
-"
-
-	    sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
-		-e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
-		  < "$nlist" >> "$output_objdir/$dlsyms"
-
-	    $echo >> "$output_objdir/$dlsyms" "\
-  {0, (lt_ptr_t) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
-  return lt_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif\
-"
-	  fi
-
-	  pic_flag_for_symtable=
-	  case "$host" in
-	  # compiling the symbol table file with pic_flag works around
-	  # a FreeBSD bug that causes programs to crash when -lm is
-	  # linked before any other PIC object.  But we must not use
-	  # pic_flag when linking with -static.  The problem exists in
-	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-	  *-*-freebsd2*|*-*-freebsd3.0*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
-	    esac
-	  esac
-
-	  # Now compile the dynamic symbol file.
-	  $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
-	  $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
-
-	  # Clean up the generated files.
-	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
-
-	  # Transform the symbol file into the correct name.
-	  compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-	  finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
-	  ;;
-	*)
-	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
-	  exit 1
-	  ;;
-	esac
-      else
-	# We keep going just in case the user didn't refer to
-	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
-	# really was required.
-
-	# Nullify the symbol file.
-	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
-	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
-      fi
-
-      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
-	# Replace the output file specification.
-	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-	link_command="$compile_command$compile_rpath"
-
-	# We have no uninstalled library dependencies, so finalize right now.
-	$show "$link_command"
-	$run eval "$link_command"
-	status=$?
-	
-	# Delete the generated files.
-	if test -n "$dlsyms"; then
-	  $show "$rm $output_objdir/${outputname}S.${objext}"
-	  $run $rm "$output_objdir/${outputname}S.${objext}"
-	fi
-
-	exit $status
-      fi
-
-      if test -n "$shlibpath_var"; then
-	# We should set the shlibpath_var
-	rpath=
-	for dir in $temp_rpath; do
-	  case "$dir" in
-	  [\\/]* | [A-Za-z]:[\\/]*)
-	    # Absolute path.
-	    rpath="$rpath$dir:"
-	    ;;
-	  *)
-	    # Relative path: add a thisdir entry.
-	    rpath="$rpath\$thisdir/$dir:"
-	    ;;
-	  esac
-	done
-	temp_rpath="$rpath"
-      fi
-
-      if test -n "$compile_shlibpath$finalize_shlibpath"; then
-	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
-      fi
-      if test -n "$finalize_shlibpath"; then
-	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
-      fi
-
-      compile_var=
-      finalize_var=
-      if test -n "$runpath_var"; then
-	if test -n "$perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-	if test -n "$finalize_perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $finalize_perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-      fi
-
-      if test "$hardcode_action" = relink; then
-	# Fast installation is not supported
-	link_command="$compile_var$compile_command$compile_rpath"
-	relink_command="$finalize_var$finalize_command$finalize_rpath"
-	
-	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
-	$echo "$modename: \`$output' will be relinked during installation" 1>&2
-      else
-	if test "$fast_install" != no; then
-	  link_command="$finalize_var$compile_command$finalize_rpath"
-	  if test "$fast_install" = yes; then
-	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
-	  else
-	    # fast_install is set to needless
-	    relink_command=
-	  fi
-	else
-	  link_command="$compile_var$compile_command$compile_rpath"
-	  relink_command="$finalize_var$finalize_command$finalize_rpath"
-	fi
-      fi
-
-      # Replace the output file specification.
-      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
-      
-      # Delete the old output files.
-      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
-
-      $show "$link_command"
-      $run eval "$link_command" || exit $?
-
-      # Now create the wrapper script.
-      $show "creating $output"
-
-      # Quote the relink command for shipping.
-      if test -n "$relink_command"; then
-	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Quote $echo for shipping.
-      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
-	case "$0" in
-	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
-	*) qecho="$SHELL `pwd`/$0 --fallback-echo";;
-	esac
-	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Only actually do things if our run command is non-null.
-      if test -z "$run"; then
-	# win32 will think the script is a binary if it has
-	# a .exe suffix, so we strip it off here.
-	case $output in
-	  *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
-	esac
-	$rm $output
-	trap "$rm $output; exit 1" 1 2 15
-
-	$echo > $output "\
-#! $SHELL
-
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
-
-relink_command=\"$relink_command\"
-
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
-  # install mode needs the following variable:
-  link_against_libtool_libs='$link_against_libtool_libs'
-else
-  # When we are sourced in execute mode, \$file and \$echo are already set.
-  if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    echo=\"$qecho\"
-    file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$echo works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$echo will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
-    fi
-  fi\
-"
-	$echo >> $output "\
-
-  # Find the directory that this script lives in.
-  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
-  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
-
-  # Follow symbolic links until we get to the real thisdir.
-  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
-  while test -n \"\$file\"; do
-    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
-
-    # If there was a directory component, then change thisdir.
-    if test \"x\$destdir\" != \"x\$file\"; then
-      case \"\$destdir\" in
-      [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
-      *) thisdir=\"\$thisdir/\$destdir\" ;;
-      esac
-    fi
-
-    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
-    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
-  done
-
-  # Try to get the absolute directory name.
-  absdir=\`cd \"\$thisdir\" && pwd\`
-  test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
-
-	if test "$fast_install" = yes; then
-	  echo >> $output "\
-  program=lt-'$outputname'
-  progdir=\"\$thisdir/$objdir\"
-  
-  if test ! -f \"\$progdir/\$program\" || \\
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
-       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
-
-    file=\"\$\$-\$program\"
-
-    if test ! -d \"\$progdir\"; then
-      $mkdir \"\$progdir\"
-    else
-      $rm \"\$progdir/\$file\"
-    fi"
-
-	  echo >> $output "\
-
-    # relink executable if necessary
-    if test -n \"\$relink_command\"; then
-      if (cd \"\$thisdir\" && eval \$relink_command); then :
-      else
-	$rm \"\$progdir/\$file\"
-	exit 1
-      fi
-    fi
-
-    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
-    { $rm \"\$progdir/\$program\";
-      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
-    $rm \"\$progdir/\$file\"
-  fi"
-	else
-	  echo >> $output "\
-  program='$outputname'
-  progdir=\"\$thisdir/$objdir\"
-"
-	fi
-
-	echo >> $output "\
-
-  if test -f \"\$progdir/\$program\"; then"
-
-	# Export our shlibpath_var if we have one.
-	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
-	  $echo >> $output "\
-    # Add our own library path to $shlibpath_var
-    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
-
-    # Some systems cannot cope with colon-terminated $shlibpath_var
-    # The second colon is a workaround for a bug in BeOS R4 sed
-    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
-
-    export $shlibpath_var
-"
-	fi
-
-	# fixup the dll searchpath if we need to.
-	if test -n "$dllsearchpath"; then
-	  $echo >> $output "\
-    # Add the dll search path components to the executable PATH
-    PATH=$dllsearchpath:\$PATH
-"
-	fi
-
-	$echo >> $output "\
-    if test \"\$libtool_execute_magic\" != \"$magic\"; then
-      # Run the actual program with our arguments.
-"
-	case $host in
-	*-*-cygwin* | *-*-mingw | *-*-os2*)
-	  # win32 systems need to use the prog path for dll
-	  # lookup to work
-	  $echo >> $output "\
-      exec \$progdir\\\\\$program \${1+\"\$@\"}
-"
-	  ;;
-	*)
-	  $echo >> $output "\
-      # Export the path to the program.
-      PATH=\"\$progdir:\$PATH\"
-      export PATH
-
-      exec \$program \${1+\"\$@\"}
-"
-	  ;;
-	esac
-	$echo >> $output "\
-      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
-      exit 1
-    fi
-  else
-    # The program doesn't exist.
-    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
-    \$echo \"This script is just a wrapper for \$program.\" 1>&2
-    echo \"See the $PACKAGE documentation for more information.\" 1>&2
-    exit 1
-  fi
-fi\
-"
-	chmod +x $output
-      fi
-      exit 0
-      ;;
-    esac
-
-    # See if we need to build an old-fashioned archive.
-    for oldlib in $oldlibs; do
-
-      if test "$build_libtool_libs" = convenience; then
-	oldobjs="$libobjs_save"
-	addlibs="$convenience"
-	build_libtool_libs=no
-      else
-	if test "$build_libtool_libs" = module; then
-	  oldobjs="$libobjs_save"
-	  build_libtool_libs=no
-	else
-	  oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
-	fi
-	addlibs="$old_convenience"
-      fi
-
-      if test -n "$addlibs"; then
-	gentop="$output_objdir/${outputname}x"
-	$show "${rm}r $gentop"
-	$run ${rm}r "$gentop"
-	$show "mkdir $gentop"
-	$run mkdir "$gentop"
-	status=$?
-	if test $status -ne 0 && test ! -d "$gentop"; then
-	  exit $status
-	fi
-	generated="$generated $gentop"
-	  
-	# Add in members from convenience archives.
-	for xlib in $addlibs; do
-	  # Extract the objects.
-	  case "$xlib" in
-	  [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
-	  *) xabs=`pwd`"/$xlib" ;;
-	  esac
-	  xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
-	  xdir="$gentop/$xlib"
-
-	  $show "${rm}r $xdir"
-	  $run ${rm}r "$xdir"
-	  $show "mkdir $xdir"
-	  $run mkdir "$xdir"
-	  status=$?
-	  if test $status -ne 0 && test ! -d "$xdir"; then
-	    exit $status
-	  fi
-	  $show "(cd $xdir && $AR x $xabs)"
-	  $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
-
-	  oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
-	done
-      fi
-
-      # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
-	eval cmds=\"$old_archive_from_new_cmds\"
-      else
-	# Ensure that we have .o objects in place incase we decided
-	# not to build a shared library, and have fallen back to building
-	# static libs even though --disable-static was passed!
-	for oldobj in $oldobjs; do
-	  if test ! -f $oldobj; then
-	    obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"`
-	    $show "${LN_S} $obj $oldobj"
-	    $run ${LN_S} $obj $oldobj || exit $?
-	  fi
-	done
-
-	eval cmds=\"$old_archive_cmds\"
-      fi
-      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
-
-    if test -n "$generated"; then
-      $show "${rm}r$generated"
-      $run ${rm}r$generated
-    fi
-
-    # Now create the libtool archive.
-    case "$output" in
-    *.la)
-      old_library=
-      test "$build_old_libs" = yes && old_library="$libname.$libext"
-      $show "creating $output"
-
-      if test -n "$xrpath"; then
-	temp_xrpath=
-	for libdir in $xrpath; do
-	  temp_xrpath="$temp_xrpath -R$libdir"
-	done
-	dependency_libs="$temp_xrpath $dependency_libs"
-      fi
-
-      # Only create the output if not a dry run.
-      if test -z "$run"; then
-	for installed in no yes; do
-	  if test "$installed" = yes; then
-	    if test -z "$install_libdir"; then
-	      break
-	    fi
-	    output="$output_objdir/$outputname"i
-	  fi
-	  $rm $output
-	  $echo > $output "\
-# $outputname - a libtool library file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='$dlname'
-
-# Names of this library.
-library_names='$library_names'
-
-# The name of the static archive.
-old_library='$old_library'
-
-# Libraries that this one depends upon.
-dependency_libs='$dependency_libs'
-
-# Version information for $libname.
-current=$current
-age=$age
-revision=$revision
-
-# Is this an already installed library?
-installed=$installed
-
-# Directory that this library needs to be installed in:
-libdir='$install_libdir'\
-"
-	done
-      fi
-
-      # Do a symbolic link so that the libtool archive can be found in
-      # LD_LIBRARY_PATH before the program is installed.
-      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
-      $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
-      ;;
-    esac
-    exit 0
-    ;;
-
-  # libtool install mode
-  install)
-    modename="$modename: install"
-
-    # There may be an optional sh(1) argument at the beginning of
-    # install_prog (especially on Windows NT).
-    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
-      # Aesthetically quote it.
-      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
-      case "$arg" in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
-	arg="\"$arg\""
-	;;
-      esac
-      install_prog="$arg "
-      arg="$1"
-      shift
-    else
-      install_prog=
-      arg="$nonopt"
-    fi
-
-    # The real first argument should be the name of the installation program.
-    # Aesthetically quote it.
-    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-    case "$arg" in
-    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
-      arg="\"$arg\""
-      ;;
-    esac
-    install_prog="$install_prog$arg"
-
-    # We need to accept at least all the BSD install flags.
-    dest=
-    files=
-    opts=
-    prev=
-    install_type=
-    isdir=no
-    stripme=
-    for arg
-    do
-      if test -n "$dest"; then
-	files="$files $dest"
-	dest="$arg"
-	continue
-      fi
-
-      case "$arg" in
-      -d) isdir=yes ;;
-      -f) prev="-f" ;;
-      -g) prev="-g" ;;
-      -m) prev="-m" ;;
-      -o) prev="-o" ;;
-      -s)
-	stripme=" -s"
-	continue
-	;;
-      -*) ;;
-
-      *)
-	# If the previous option needed an argument, then skip it.
-	if test -n "$prev"; then
-	  prev=
-	else
-	  dest="$arg"
-	  continue
-	fi
-	;;
-      esac
-
-      # Aesthetically quote the argument.
-      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-      case "$arg" in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
-	arg="\"$arg\""
-	;;
-      esac
-      install_prog="$install_prog $arg"
-    done
-
-    if test -z "$install_prog"; then
-      $echo "$modename: you must specify an install program" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prev' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    if test -z "$files"; then
-      if test -z "$dest"; then
-	$echo "$modename: no file or destination specified" 1>&2
-      else
-	$echo "$modename: you must specify a destination" 1>&2
-      fi
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    # Strip any trailing slash from the destination.
-    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
-
-    # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=yes
-    if test "$isdir" = yes; then
-      destdir="$dest"
-      destname=
-    else
-      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
-      test "X$destdir" = "X$dest" && destdir=.
-      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
-
-      # Not a directory, so check to see that there is only one file specified.
-      set dummy $files
-      if test $# -gt 2; then
-	$echo "$modename: \`$dest' is not a directory" 1>&2
-	$echo "$help" 1>&2
-	exit 1
-      fi
-    fi
-    case "$destdir" in
-    [\\/]* | [A-Za-z]:[\\/]*) ;;
-    *)
-      for file in $files; do
-	case "$file" in
-	*.lo) ;;
-	*)
-	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
-	  $echo "$help" 1>&2
-	  exit 1
-	  ;;
-	esac
-      done
-      ;;
-    esac
-
-    # This variable tells wrapper scripts just to set variables rather
-    # than running their programs.
-    libtool_install_magic="$magic"
-
-    staticlibs=
-    future_libdirs=
-    current_libdirs=
-    for file in $files; do
-
-      # Do each installation.
-      case "$file" in
-      *.a | *.lib)
-	# Do the static libraries later.
-	staticlibs="$staticlibs $file"
-	;;
-
-      *.la)
-	# Check to see that this really is a libtool archive.
-	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
-	  $echo "$help" 1>&2
-	  exit 1
-	fi
-
-	library_names=
-	old_library=
-	# If there is no directory component, then add one.
-	case "$file" in
-	*/* | *\\*) . $file ;;
-	*) . ./$file ;;
-	esac
-
-	# Add the libdir to current_libdirs if it is the destination.
-	if test "X$destdir" = "X$libdir"; then
-	  case "$current_libdirs " in
-	  *" $libdir "*) ;;
-	  *) current_libdirs="$current_libdirs $libdir" ;;
-	  esac
-	else
-	  # Note the libdir as a future libdir.
-	  case "$future_libdirs " in
-	  *" $libdir "*) ;;
-	  *) future_libdirs="$future_libdirs $libdir" ;;
-	  esac
-	fi
-
-	dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
-	test "X$dir" = "X$file/" && dir=
-	dir="$dir$objdir"
-
-	# See the names of the shared library.
-	set dummy $library_names
-	if test -n "$2"; then
-	  realname="$2"
-	  shift
-	  shift
-
-	  # Install the shared library and build the symlinks.
-	  $show "$install_prog $dir/$realname $destdir/$realname"
-	  $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
-	  test "X$dlname" = "X$realname" && dlname=
-
-	  if test $# -gt 0; then
-	    # Delete the old symlinks, and create new ones.
-	    for linkname
-	    do
-	      test "X$dlname" = "X$linkname" && dlname=
-	      if test "$linkname" != "$realname"; then
-		$show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
-		$run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
-	      fi
-	    done
-	  fi
-
-	  if test -n "$dlname"; then
-	    # Install the dynamically-loadable library.
-	    $show "$install_prog $dir/$dlname $destdir/$dlname"
-	    $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
-	  fi
-
-	  # Do each command in the postinstall commands.
-	  lib="$destdir/$realname"
-	  eval cmds=\"$postinstall_cmds\"
-	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	  for cmd in $cmds; do
-	    IFS="$save_ifs"
-	    $show "$cmd"
-	    $run eval "$cmd" || exit $?
-	  done
-	  IFS="$save_ifs"
-	fi
-
-	# Install the pseudo-library for information purposes.
-	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	instname="$dir/$name"i
-	$show "$install_prog $instname $destdir/$name"
-	$run eval "$install_prog $instname $destdir/$name" || exit $?
-
-	# Maybe install the static library, too.
-	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
-	;;
-
-      *.lo)
-	# Install (i.e. copy) a libtool object.
-
-	# Figure out destination file name, if it wasn't already specified.
-	if test -n "$destname"; then
-	  destfile="$destdir/$destname"
-	else
-	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	  destfile="$destdir/$destfile"
-	fi
-
-	# Deduce the name of the destination old-style object file.
-	case "$destfile" in
-	*.lo)
-	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
-	  ;;
-	*.o | *.obj)
-	  staticdest="$destfile"
-	  destfile=
-	  ;;
-	*)
-	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
-	  $echo "$help" 1>&2
-	  exit 1
-	  ;;
-	esac
-
-	# Install the libtool object if requested.
-	if test -n "$destfile"; then
-	  $show "$install_prog $file $destfile"
-	  $run eval "$install_prog $file $destfile" || exit $?
-	fi
-
-	# Install the old object if enabled.
-	if test "$build_old_libs" = yes; then
-	  # Deduce the name of the old-style object file.
-	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
-
-	  $show "$install_prog $staticobj $staticdest"
-	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
-	fi
-	exit 0
-	;;
-
-      *)
-	# Figure out destination file name, if it wasn't already specified.
-	if test -n "$destname"; then
-	  destfile="$destdir/$destname"
-	else
-	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-	  destfile="$destdir/$destfile"
-	fi
-
-	# Do a test to see if this is really a libtool program.
-	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  link_against_libtool_libs=
-	  relink_command=
-
-	  # If there is no directory component, then add one.
-	  case "$file" in
-	  */* | *\\*) . $file ;;
-	  *) . ./$file ;;
-	  esac
-
-	  # Check the variables that should have been set.
-	  if test -z "$link_against_libtool_libs"; then
-	    $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
-	    exit 1
-	  fi
-
-	  finalize=yes
-	  for lib in $link_against_libtool_libs; do
-	    # Check to see that each library is installed.
-	    libdir=
-	    if test -f "$lib"; then
-	      # If there is no directory component, then add one.
-	      case "$lib" in
-	      */* | *\\*) . $lib ;;
-	      *) . ./$lib ;;
-	      esac
-	    fi
-	    libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
-	    if test -n "$libdir" && test ! -f "$libfile"; then
-	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
-	      finalize=no
-	    fi
-	  done
-
-	  outputname=
-	  if test "$fast_install" = no && test -n "$relink_command"; then
-	    if test "$finalize" = yes && test -z "$run"; then
-	      tmpdir="/tmp"
-	      test -n "$TMPDIR" && tmpdir="$TMPDIR"
-	      tmpdir="$tmpdir/libtool-$$"
-	      if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
-	      else
-		$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
-		continue
-	      fi
-	      outputname="$tmpdir/$file"
-	      # Replace the output file specification.
-	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
-
-	      $show "$relink_command"
-	      if $run eval "$relink_command"; then :
-	      else
-		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
-		${rm}r "$tmpdir"
-		continue
-	      fi
-	      file="$outputname"
-	    else
-	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
-	    fi
-	  else
-	    # Install the binary that we compiled earlier.
-	    file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
-	  fi
-	fi
-
-	$show "$install_prog$stripme $file $destfile"
-	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
-	test -n "$outputname" && ${rm}r "$tmpdir"
-	;;
-      esac
-    done
-
-    for file in $staticlibs; do
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-
-      # Set up the ranlib parameters.
-      oldlib="$destdir/$name"
-
-      $show "$install_prog $file $oldlib"
-      $run eval "$install_prog \$file \$oldlib" || exit $?
-
-      # Do each command in the postinstall commands.
-      eval cmds=\"$old_postinstall_cmds\"
-      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
-    done
-
-    if test -n "$future_libdirs"; then
-      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
-    fi
-
-    if test -n "$current_libdirs"; then
-      # Maybe just do a dry run.
-      test -n "$run" && current_libdirs=" -n$current_libdirs"
-      exec $SHELL $0 --finish$current_libdirs
-      exit 1
-    fi
-
-    exit 0
-    ;;
-
-  # libtool finish mode
-  finish)
-    modename="$modename: finish"
-    libdirs="$nonopt"
-    admincmds=
-
-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
-      for dir
-      do
-	libdirs="$libdirs $dir"
-      done
-
-      for libdir in $libdirs; do
-	if test -n "$finish_cmds"; then
-	  # Do each command in the finish commands.
-	  eval cmds=\"$finish_cmds\"
-	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	  for cmd in $cmds; do
-	    IFS="$save_ifs"
-	    $show "$cmd"
-	    $run eval "$cmd" || admincmds="$admincmds
-       $cmd"
-	  done
-	  IFS="$save_ifs"
-	fi
-	if test -n "$finish_eval"; then
-	  # Do the single finish_eval.
-	  eval cmds=\"$finish_eval\"
-	  $run eval "$cmds" || admincmds="$admincmds
-       $cmds"
-	fi
-      done
-    fi
-
-    # Exit here if they wanted silent mode.
-    test "$show" = : && exit 0
-
-    echo "----------------------------------------------------------------------"
-    echo "Libraries have been installed in:"
-    for libdir in $libdirs; do
-      echo "   $libdir"
-    done
-    echo
-    echo "If you ever happen to want to link against installed libraries"
-    echo "in a given directory, LIBDIR, you must either use libtool, and"
-    echo "specify the full pathname of the library, or use \`-LLIBDIR'"
-    echo "flag during linking and do at least one of the following:"
-    if test -n "$shlibpath_var"; then
-      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
-      echo "     during execution"
-    fi
-    if test -n "$runpath_var"; then
-      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
-      echo "     during linking"
-    fi
-    if test -n "$hardcode_libdir_flag_spec"; then
-      libdir=LIBDIR
-      eval flag=\"$hardcode_libdir_flag_spec\"
-
-      echo "   - use the \`$flag' linker flag"
-    fi
-    if test -n "$admincmds"; then
-      echo "   - have your system administrator run these commands:$admincmds"
-    fi
-    if test -f /etc/ld.so.conf; then
-      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
-    fi
-    echo
-    echo "See any operating system documentation about shared libraries for"
-    echo "more information, such as the ld(1) and ld.so(8) manual pages."
-    echo "----------------------------------------------------------------------"
-    exit 0
-    ;;
-
-  # libtool execute mode
-  execute)
-    modename="$modename: execute"
-
-    # The first argument is the command name.
-    cmd="$nonopt"
-    if test -z "$cmd"; then
-      $echo "$modename: you must specify a COMMAND" 1>&2
-      $echo "$help"
-      exit 1
-    fi
-
-    # Handle -dlopen flags immediately.
-    for file in $execute_dlfiles; do
-      if test ! -f "$file"; then
-	$echo "$modename: \`$file' is not a file" 1>&2
-	$echo "$help" 1>&2
-	exit 1
-      fi
-
-      dir=
-      case "$file" in
-      *.la)
-	# Check to see that this really is a libtool archive.
-	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-	  $echo "$help" 1>&2
-	  exit 1
-	fi
-
-	# Read the libtool library.
-	dlname=
-	library_names=
-
-	# If there is no directory component, then add one.
-	case "$file" in
-	*/* | *\\*) . $file ;;
-	*) . ./$file ;;
-	esac
-
-	# Skip this library if it cannot be dlopened.
-	if test -z "$dlname"; then
-	  # Warn if it was a shared library.
-	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
-	  continue
-	fi
-
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$dir" = "X$file" && dir=.
-
-	if test -f "$dir/$objdir/$dlname"; then
-	  dir="$dir/$objdir"
-	else
-	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
-	  exit 1
-	fi
-	;;
-
-      *.lo)
-	# Just add the directory containing the .lo file.
-	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$dir" = "X$file" && dir=.
-	;;
-
-      *)
-	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
-	continue
-	;;
-      esac
-
-      # Get the absolute pathname.
-      absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir="$absdir"
-
-      # Now add the directory to shlibpath_var.
-      if eval "test -z \"\$$shlibpath_var\""; then
-	eval "$shlibpath_var=\"\$dir\""
-      else
-	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
-      fi
-    done
-
-    # This variable tells wrapper scripts just to set shlibpath_var
-    # rather than running their programs.
-    libtool_execute_magic="$magic"
-
-    # Check if any of the arguments is a wrapper script.
-    args=
-    for file
-    do
-      case "$file" in
-      -*) ;;
-      *)
-	# Do a test to see if this is really a libtool program.
-	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  # If there is no directory component, then add one.
-	  case "$file" in
-	  */* | *\\*) . $file ;;
-	  *) . ./$file ;;
-	  esac
-
-	  # Transform arg to wrapped name.
-	  file="$progdir/$program"
-	fi
-	;;
-      esac
-      # Quote arguments (to preserve shell metacharacters).
-      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
-      args="$args \"$file\""
-    done
-
-    if test -z "$run"; then
-      # Export the shlibpath_var.
-      eval "export $shlibpath_var"
-
-      # Restore saved enviroment variables
-      if test "${save_LC_ALL+set}" = set; then
-	LC_ALL="$save_LC_ALL"; export LC_ALL
-      fi
-      if test "${save_LANG+set}" = set; then
-	LANG="$save_LANG"; export LANG
-      fi
-
-      # Now actually exec the command.
-      eval "exec \$cmd$args"
-
-      $echo "$modename: cannot exec \$cmd$args"
-      exit 1
-    else
-      # Display what would be done.
-      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
-      $echo "export $shlibpath_var"
-      $echo "$cmd$args"
-      exit 0
-    fi
-    ;;
-
-  # libtool uninstall mode
-  uninstall)
-    modename="$modename: uninstall"
-    rm="$nonopt"
-    files=
-
-    for arg
-    do
-      case "$arg" in
-      -*) rm="$rm $arg" ;;
-      *) files="$files $arg" ;;
-      esac
-    done
-
-    if test -z "$rm"; then
-      $echo "$modename: you must specify an RM program" 1>&2
-      $echo "$help" 1>&2
-      exit 1
-    fi
-
-    for file in $files; do
-      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
-      test "X$dir" = "X$file" && dir=.
-      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-
-      rmfiles="$file"
-
-      case "$name" in
-      *.la)
-	# Possibly a libtool archive, so verify it.
-	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  . $dir/$name
-
-	  # Delete the libtool libraries and symlinks.
-	  for n in $library_names; do
-	    rmfiles="$rmfiles $dir/$n"
-	    test "X$n" = "X$dlname" && dlname=
-	  done
-	  test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
-	  test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
-
-	  $show "$rm $rmfiles"
-	  $run $rm $rmfiles
-
-	  if test -n "$library_names"; then
-	    # Do each command in the postuninstall commands.
-	    eval cmds=\"$postuninstall_cmds\"
-	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	    for cmd in $cmds; do
-	      IFS="$save_ifs"
-	      $show "$cmd"
-	      $run eval "$cmd"
-	    done
-	    IFS="$save_ifs"
-	  fi
-
-	  if test -n "$old_library"; then
-	    # Do each command in the old_postuninstall commands.
-	    eval cmds=\"$old_postuninstall_cmds\"
-	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
-	    for cmd in $cmds; do
-	      IFS="$save_ifs"
-	      $show "$cmd"
-	      $run eval "$cmd"
-	    done
-	    IFS="$save_ifs"
-	  fi
-
-	  # FIXME: should reinstall the best remaining shared library.
-	fi
-	;;
-
-      *.lo)
-	if test "$build_old_libs" = yes; then
-	  oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
-	  rmfiles="$rmfiles $dir/$oldobj"
-	fi
-	$show "$rm $rmfiles"
-	$run $rm $rmfiles
-	;;
-
-      *)
-	$show "$rm $rmfiles"
-	$run $rm $rmfiles
-	;;
-      esac
-    done
-    exit 0
-    ;;
-
-  "")
-    $echo "$modename: you must specify a MODE" 1>&2
-    $echo "$generic_help" 1>&2
-    exit 1
-    ;;
-  esac
-
-  $echo "$modename: invalid operation mode \`$mode'" 1>&2
-  $echo "$generic_help" 1>&2
-  exit 1
-fi # test -z "$show_help"
-
-# We need to display help for each of the modes.
-case "$mode" in
-"") $echo \
-"Usage: $modename [OPTION]... [MODE-ARG]...
-
-Provide generalized library-building support services.
-
-    --config          show all configuration variables
-    --debug           enable verbose shell tracing
--n, --dry-run         display commands without modifying any files
-    --features        display basic configuration information and exit
-    --finish          same as \`--mode=finish'
-    --help            display this help message and exit
-    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
-    --quiet           same as \`--silent'
-    --silent          don't print informational messages
-    --version         print version information
-
-MODE must be one of the following:
-
-      compile         compile a source file into a libtool object
-      execute         automatically set library path, then run a program
-      finish          complete the installation of libtool libraries
-      install         install libraries or executables
-      link            create a library or an executable
-      uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
-a more detailed description of MODE."
-  exit 0
-  ;;
-
-compile)
-  $echo \
-"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
-
-Compile a source file into a libtool library object.
-
-This mode accepts the following additional options:
-
-  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
-  -static           always build a \`.o' file suitable for static linking
-
-COMPILE-COMMAND is a command to be used in creating a \`standard' object file
-from the given SOURCEFILE.
-
-The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix \`.c' with the
-library object suffix, \`.lo'."
-  ;;
-
-execute)
-  $echo \
-"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
-
-Automatically set library path, then run a program.
-
-This mode accepts the following additional options:
-
-  -dlopen FILE      add the directory containing FILE to the library path
-
-This mode sets the library path environment variable according to \`-dlopen'
-flags.
-
-If any of the ARGS are libtool executable wrappers, then they are translated
-into their corresponding uninstalled binary, and any of their required library
-directories are added to the library path.
-
-Then, COMMAND is executed, with ARGS as arguments."
-  ;;
-
-finish)
-  $echo \
-"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
-
-Complete the installation of libtool libraries.
-
-Each LIBDIR is a directory that contains libtool libraries.
-
-The commands that this mode executes may require superuser privileges.  Use
-the \`--dry-run' option if you just want to see what would be executed."
-  ;;
-
-install)
-  $echo \
-"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
-
-Install executables or libraries.
-
-INSTALL-COMMAND is the installation command.  The first component should be
-either the \`install' or \`cp' program.
-
-The rest of the components are interpreted as arguments to that command (only
-BSD-compatible install options are recognized)."
-  ;;
-
-link)
-  $echo \
-"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
-
-Link object files or libraries together to form another library, or to
-create an executable program.
-
-LINK-COMMAND is a command using the C compiler that you would use to create
-a program from several object files.
-
-The following components of LINK-COMMAND are treated specially:
-
-  -all-static       do not do any dynamic linking at all
-  -avoid-version    do not add a version suffix if possible
-  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
-  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
-  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
-  -export-symbols SYMFILE
-		    try to export only the symbols listed in SYMFILE
-  -export-symbols-regex REGEX
-		    try to export only the symbols matching REGEX
-  -LLIBDIR          search LIBDIR for required installed libraries
-  -lNAME            OUTPUT-FILE requires the installed library libNAME
-  -module           build a library that can dlopened
-  -no-undefined     declare that a library does not refer to external symbols
-  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -release RELEASE  specify package release information
-  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
-  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
-  -static           do not do any dynamic linking of libtool libraries
-  -version-info CURRENT[:REVISION[:AGE]]
-		    specify library version info [each variable defaults to 0]
-
-All other options (arguments beginning with \`-') are ignored.
-
-Every other argument is treated as a filename.  Files ending in \`.la' are
-treated as uninstalled libtool libraries, other files are standard or library
-object files.
-
-If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
-only library objects (\`.lo' files) may be specified, and \`-rpath' is
-required, except when creating a convenience library.
-
-If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
-using \`ar' and \`ranlib', or on Windows using \`lib'.
-
-If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
-is created, otherwise an executable program is created."
-  ;;
-
-uninstall)
-  $echo \
-"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
-
-Remove libraries from an installation directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, all the files associated with it are deleted.
-Otherwise, only FILE itself is deleted using RM."
-  ;;
-
-*)
-  $echo "$modename: invalid operation mode \`$mode'" 1>&2
-  $echo "$help" 1>&2
-  exit 1
-  ;;
-esac
-
-echo
-$echo "Try \`$modename --help' for more information about other modes."
-
-exit 0
-
-# Local Variables:
-# mode:shell-script
-# sh-indentation:2
-# End:
diff --git a/makefile.vc b/makefile.vc
index 0819a21..cc5dc74 100644
--- a/makefile.vc
+++ b/makefile.vc
@@ -1,10 +1,17 @@
 
 #CFLAGS	=	/DSHPAPI_CALL=__stdcall
+CFLAGS =	/nologo /Ox /MD /DSHAPELIB_DLLEXPORT
 
-default:	all
+IMPORT_LIB	= shapelib_i.lib
+STATIC_LIB	= shapelib.lib
+DLLNAME 	= shapelib.dll
+LINK_LIB 	= $(IMPORT_LIB)
 
-all:	shpcreate.exe shpadd.exe shpdump.exe shprewind.exe dbfcreate.exe \
-	dbfadd.exe dbfdump.exe shptest.exe shptreedump.exe shapelib.dll
+OBJ 		= shpopen.obj dbfopen.obj shptree.obj safileio.obj 
+
+all:	$(STATIC_LIB) $(DLLNAME) \
+	shpcreate.exe shpadd.exe shpdump.exe shprewind.exe dbfcreate.exe \
+	dbfadd.exe dbfdump.exe shptest.exe shptreedump.exe
 
 shpopen.obj:	shpopen.c shapefil.h
 	$(CC) $(CFLAGS) -c shpopen.c
@@ -15,41 +22,65 @@ shptree.obj:	shptree.c shapefil.h
 dbfopen.obj:	dbfopen.c shapefil.h
 	$(CC) $(CFLAGS) -c dbfopen.c
 
-shpcreate.exe:	shpcreate.c shpopen.obj
-	$(CC) $(CFLAGS) shpcreate.c shpopen.obj $(LINKOPT) -o shpcreate
+safileio.obj:	safileio.c shapefil.h
+	$(CC) $(CFLAGS) -c safileio.c
+
+shpcreate.exe:	shpcreate.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shpcreate.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
+
+shpadd.exe:		shpadd.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shpadd.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-shpadd.exe:		shpadd.c shpopen.obj
-	$(CC) $(CFLAGS) shpadd.c shpopen.obj $(LINKOPT)
+shpdump.exe:	shpdump.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shpdump.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-shpdump.exe:	shpdump.c shpopen.obj
-	$(CC) $(CFLAGS) shpdump.c shpopen.obj $(LINKOPT)
+shprewind.exe:	shprewind.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shprewind.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-shprewind.exe:	shprewind.c shpopen.obj
-	$(CC) $(CFLAGS) shprewind.c shpopen.obj $(LINKOPT)
+dbfcreate.exe:	dbfcreate.c $(LINK_LIB)
+	$(CC) $(CFLAGS) dbfcreate.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-dbfcreate.exe:	dbfcreate.c dbfopen.obj
-	$(CC) $(CFLAGS) dbfcreate.c dbfopen.obj $(LINKOPT)
+dbfadd.exe:	dbfadd.c $(LINK_LIB)
+	$(CC) $(CFLAGS) dbfadd.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-dbfadd.exe:	dbfadd.c dbfopen.obj
-	$(CC) $(CFLAGS) dbfadd.c dbfopen.obj $(LINKOPT)
+dbfdump.exe:	dbfdump.c $(LINK_LIB)
+	$(CC) $(CFLAGS) dbfdump.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-dbfdump.exe:	dbfdump.c dbfopen.obj
-	$(CC) $(CFLAGS) dbfdump.c dbfopen.obj $(LINKOPT)
+shptest.exe:	shptest.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shptest.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-shptest.exe:	shptest.c shpopen.obj
-	$(CC) $(CFLAGS) shptest.c shpopen.obj $(LINKOPT)
+shputils.exe:	shputils.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shputils.c $(LINK_LIB) $(LINKOPT) 
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-shputils.exe:	shputils.c shpopen.obj dbfopen.obj
-	$(CC) $(CFLAGS) shputils.c shpopen.obj dbfopen.obj $(LINKOPT) 
+shptreedump.exe:	shptreedump.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shptreedump.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
-shptreedump.exe:	shptreedump.c shptree.obj shpopen.obj
-	$(CC) $(CFLAGS) shptreedump.c shptree.obj shpopen.obj $(LINKOPT)
+shpdiff.exe:	shpdiff.c $(LINK_LIB)
+	$(CC) $(CFLAGS) shpdiff.c $(LINK_LIB) $(LINKOPT)
+	if exist $@.manifest mt -manifest $@.manifest -outputresource:$@;1
 
 clean:
-	-del *.obj dbfdump dbfcreate dbfadd shpdump shpcreate shpadd shputils
+	-del *.obj 
+	-del *.exe
 	-del *.lib
 	-del *.dll
+	-del *.manifest
+
+$(STATIC_LIB):	$(OBJ)
+	lib /nologo /out:$(STATIC_LIB) $(OBJ)
+
+$(IMPORT_LIB):	$(DLLNAME)
 
-shapelib.dll:    shpopen.obj dbfopen.obj shptree.obj shapelib.def
-	link /dll /def:shapelib.def /out:shapelib.dll /implib:shapelib.lib \
-		shpopen.obj dbfopen.obj shptree.obj 
+$(DLLNAME):     $(OBJ)
+	link /nologo /dll /out:$(DLLNAME) /implib:$(IMPORT_LIB) $(OBJ)
+	if exist $(DLLNAME).manifest mt /nologo -manifest $(DLLNAME).manifest -outputresource:$(DLLNAME);2
diff --git a/makeshape.sh b/makeshape.sh
index 6e5f271..7eb088a 100755
--- a/makeshape.sh
+++ b/makeshape.sh
@@ -5,17 +5,17 @@
 #	should display in ARCView II.
 #
 
-shpcreate test polygon
-dbfcreate test.dbf -s Description 30 -n TestInt 6 0 -n TestDouble 16 5
+./shpcreate test polygon
+./dbfcreate test.dbf -s Description 30 -n TestInt 6 0 -n TestDouble 16 5
 
-shpadd test 0 0 100 0 100 100 0 100 0 0 + 20 20 20 30 30 30 20 20
-dbfadd test.dbf "Square with triangle missing" 1.5 2.5
+./shpadd test 0 0 100 0 100 100 0 100 0 0 + 20 20 20 30 30 30 20 20
+./dbfadd test.dbf "Square with triangle missing" 1.5 2.5
 
-shpadd test 150 150 160 150 180 170 150 150
-dbfadd test.dbf "Smaller triangle" 100 1000.25
+./shpadd test 150 150 160 150 180 170 150 150
+./dbfadd test.dbf "Smaller triangle" 100 1000.25
 
-shpadd test 150 150 160 150 180 170 150 150
-dbfadd test.dbf "" "" ""
+./shpadd test 150 150 160 150 180 170 150 150
+./dbfadd test.dbf "" "" ""
 
-shpdump test.shp
-dbfdump test.dbf
+./shpdump test.shp
+./dbfdump test.dbf
diff --git a/mkdist.sh b/mkdist.sh
new file mode 100755
index 0000000..829325d
--- /dev/null
+++ b/mkdist.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+if [ $# -lt 1 ] ; then
+  echo "Usage: mkdist.sh <version>"
+  echo " <version> - version number used in name of generated archive."
+  echo "Example: mkdist.sh 1.1.4"
+  exit
+fi
+
+VERSION=$1
+
+rm -rf dist_wrk
+mkdir dist_wrk
+cd dist_wrk
+
+REP=:pserver:cvsanon at cvs.maptools.org:/cvs/maptools/cvsroot
+if cvs -d $REP co shapelib ; then
+  echo checkout succeeds.
+else
+  cvs -d $REP login
+  cvs -d $REP co shapelib 
+fi 
+
+if [ ! -d shapelib ] ; then
+  exit 1
+fi
+
+mv shapelib shapelib-$VERSION
+
+find . -name CVS -type d -exec echo rm -rf {} \;
+
+tar czvf ../shapelib-$VERSION.tar.gz shapelib-$VERSION
+zip -r ../shapelib-$VERSION.zip shapelib-$VERSION
+cd ..
+rm -rf dist_wrk
+
+
diff --git a/mkrelease.sh b/mkrelease.sh
new file mode 100755
index 0000000..a25f9aa
--- /dev/null
+++ b/mkrelease.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# mkrelease.sh - prepares Shapelib source distribution package
+#
+if [ $# -lt 1 ] ; then
+  echo "Usage: mkrelease.sh <version>"
+  echo " <version> - version number used in name of generated archive."
+  echo
+  echo "Example: mkrelease 1.3.0beta1"
+  exit
+fi
+
+#
+# Processing script input arguments
+#
+VERSION=$1
+
+#
+# Checkout Shapelib sources from the repository
+#
+echo "* Downloading Shapelib sources from CVS..."
+rm -rf dist_wrk  
+mkdir dist_wrk
+cd dist_wrk
+
+cvs -d :pserver:cvsanon at cvs.maptools.org:/cvs/maptools/cvsroot export -D now shapelib 
+
+if [ \! -d shapelib ] ; then
+	echo "checkout reported an error ..."
+        echo "perhaps you need to do:"
+        echo "cvs -d :pserver:cvsanon at cvs.maptools.org:/cvs/maptools/cvsroot login"
+	cd ..
+	rm -rf dist_wrk
+	exit
+fi
+
+#
+# Make distribution packages
+#
+echo "* Making distribution packages..."
+
+mv shapelib shapelib-${VERSION}
+
+rm -f ../shapelib-${VERSION}.tar.gz ../shapelib-${VERSION}.zip
+
+tar cf ../shapelib-${VERSION}.tar shapelib-${VERSION}
+gzip -9 ../shapelib-${VERSION}.tar
+zip -r ../shapelib-${VERSION}.zip shapelib-${VERSION}
+
+echo "* Cleaning..."
+cd ..
+rm -rf dist_wrk
+
+echo "*** The End ***"
+
diff --git a/safileio.c b/safileio.c
new file mode 100644
index 0000000..f3affe2
--- /dev/null
+++ b/safileio.c
@@ -0,0 +1,286 @@
+/******************************************************************************
+ * $Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Default implementation of file io based on stdio.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2007, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: safileio.c,v $
+ * Revision 1.4  2008-01-16 20:05:14  bram
+ * Add file hooks that accept UTF-8 encoded filenames on some platforms.  Use SASetupUtf8Hooks
+ *  tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability.  Currently, this
+ *  is only available on the Windows platform that decodes the UTF-8 filenames to wide
+ *  character strings and feeds them to _wfopen and _wremove.
+ *
+ * Revision 1.3  2007/12/18 18:28:11  bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
+ *
+ * Revision 1.2  2007/12/15 20:25:30  bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function.  This is 
+ * either the number from the LDID header field ("LDID/<number>") or as the 
+ * content of an accompanying .CPG file.  When creating a DBF file, the code can
+ * be set using DBFCreateEx.
+ *
+ * Revision 1.1  2007/12/06 06:56:41  fwarmerdam
+ * new
+ *
+ */
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+SHP_CVSID("$Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $");
+
+#ifdef SHPAPI_UTF8_HOOKS
+#   ifdef SHPAPI_WINDOWS
+#       define WIN32_LEAN_AND_MEAN
+#       define NOMINMAX
+#       include <windows.h>
+#       pragma comment(lib, "kernel32.lib")
+#   endif
+#endif
+
+/************************************************************************/
+/*                              SADFOpen()                              */
+/************************************************************************/
+
+SAFile SADFOpen( const char *pszFilename, const char *pszAccess )
+
+{
+    return (SAFile) fopen( pszFilename, pszAccess );
+}
+
+/************************************************************************/
+/*                              SADFRead()                              */
+/************************************************************************/
+
+SAOffset SADFRead( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+    return (SAOffset) fread( p, (size_t) size, (size_t) nmemb, 
+                             (FILE *) file );
+}
+
+/************************************************************************/
+/*                             SADFWrite()                              */
+/************************************************************************/
+
+SAOffset SADFWrite( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+    return (SAOffset) fwrite( p, (size_t) size, (size_t) nmemb, 
+                              (FILE *) file );
+}
+
+/************************************************************************/
+/*                              SADFSeek()                              */
+/************************************************************************/
+
+SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
+
+{
+    return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
+}
+
+/************************************************************************/
+/*                              SADFTell()                              */
+/************************************************************************/
+
+SAOffset SADFTell( SAFile file )
+
+{
+    return (SAOffset) ftell( (FILE *) file );
+}
+
+/************************************************************************/
+/*                             SADFFlush()                              */
+/************************************************************************/
+
+int SADFFlush( SAFile file )
+
+{
+    return fflush( (FILE *) file );
+}
+
+/************************************************************************/
+/*                             SADFClose()                              */
+/************************************************************************/
+
+int SADFClose( SAFile file )
+
+{
+    return fclose( (FILE *) file );
+}
+
+/************************************************************************/
+/*                             SADFClose()                              */
+/************************************************************************/
+
+int SADRemove( const char *filename )
+
+{
+    return remove( filename );
+}
+
+/************************************************************************/
+/*                              SADError()                              */
+/************************************************************************/
+
+void SADError( const char *message )
+
+{
+    fprintf( stderr, "%s\n", message );
+}
+
+/************************************************************************/
+/*                        SASetupDefaultHooks()                         */
+/************************************************************************/
+
+void SASetupDefaultHooks( SAHooks *psHooks )
+
+{
+    psHooks->FOpen   = SADFOpen;
+    psHooks->FRead   = SADFRead;
+    psHooks->FWrite  = SADFWrite;
+    psHooks->FSeek   = SADFSeek;
+    psHooks->FTell   = SADFTell;
+    psHooks->FFlush  = SADFFlush;
+    psHooks->FClose  = SADFClose;
+    psHooks->Remove  = SADRemove;
+
+    psHooks->Error   = SADError;
+    psHooks->Atof    = atof;
+}
+
+
+
+
+#ifdef SHPAPI_WINDOWS
+
+/************************************************************************/
+/*                          Utf8ToWideChar                              */
+/************************************************************************/
+
+const wchar_t* Utf8ToWideChar( const char *pszFilename )
+{
+    int nMulti, nWide;
+    wchar_t *pwszFileName;
+    
+    nMulti = strlen(pszFilename) + 1;
+    nWide = MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, 0, 0);
+    if( nWide == 0 )
+    {
+        return NULL;
+    }
+    pwszFileName = (wchar_t*) malloc(nWide * sizeof(wchar_t));
+    if ( pwszFileName == NULL )
+    {
+        return NULL;
+    }
+    if( MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, pwszFileName, nWide ) == 0 )
+    {
+        free( pwszFileName );
+        return NULL;
+    }
+    return pwszFileName;
+}
+
+/************************************************************************/
+/*                           SAUtf8WFOpen                               */
+/************************************************************************/
+
+SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess )
+{
+    SAFile file = NULL;
+    const wchar_t *pwszFileName, *pwszAccess;
+    pwszFileName = Utf8ToWideChar( pszFilename );
+    pwszAccess = Utf8ToWideChar( pszAccess );
+    if( pwszFileName != NULL && pwszFileName != NULL)
+    {
+        file = (SAFile) _wfopen( pwszFileName, pwszAccess );
+    }
+    free ((wchar_t*) pwszFileName);
+    free ((wchar_t*) pwszAccess);
+    return file;
+}
+
+/************************************************************************/
+/*                             SAUtf8WRemove()                          */
+/************************************************************************/
+
+int SAUtf8WRemove( const char *pszFilename )
+{
+    const wchar_t *pwszFileName = Utf8ToWideChar( pszFilename );
+    int rc = -1; 
+    if( pwszFileName != NULL )
+    {
+        rc = _wremove( pwszFileName );
+    }
+    free ((wchar_t*) pwszFileName);
+    return rc;
+}
+
+#endif
+
+#ifdef SHPAPI_UTF8_HOOKS
+
+/************************************************************************/
+/*                          SASetupUtf8Hooks()                          */
+/************************************************************************/
+
+void SASetupUtf8Hooks( SAHooks *psHooks )
+{
+#ifdef SHPAPI_WINDOWS    
+    psHooks->FOpen   = SAUtf8WFOpen;
+    psHooks->Remove  = SAUtf8WRemove;
+#else
+#   error "no implementations of UTF-8 hooks available for this platform"
+#endif
+    psHooks->FRead   = SADFRead;
+    psHooks->FWrite  = SADFWrite;
+    psHooks->FSeek   = SADFSeek;
+    psHooks->FTell   = SADFTell;
+    psHooks->FFlush  = SADFFlush;
+    psHooks->FClose  = SADFClose;
+
+    psHooks->Error   = SADError;
+    psHooks->Atof    = atof;
+}
+
+#endif
diff --git a/shapefil.h b/shapefil.h
index 19ba921..e90b1cc 100644
--- a/shapefil.h
+++ b/shapefil.h
@@ -1,8 +1,8 @@
-#ifndef _SHAPEFILE_H_INCLUDED
-#define _SHAPEFILE_H_INCLUDED
+#ifndef SHAPEFILE_H_INCLUDED
+#define SHAPEFILE_H_INCLUDED
 
 /******************************************************************************
- * $Id: shapefil.h,v 1.26 2002/09/29 00:00:08 warmerda Exp $
+ * $Id: shapefil.h,v 1.52 2011-12-11 22:26:46 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Primary include file for Shapelib.
@@ -37,81 +37,107 @@
  ******************************************************************************
  *
  * $Log: shapefil.h,v $
- * Revision 1.26  2002/09/29 00:00:08  warmerda
- * added FTLogical and logical attribute read/write calls
+ * Revision 1.52  2011-12-11 22:26:46  fwarmerdam
+ * upgrade .qix access code to use SAHooks (gdal #3365)
  *
- * Revision 1.25  2002/05/07 13:46:30  warmerda
- * added DBFWriteAttributeDirectly().
+ * Revision 1.51  2011-07-24 05:59:25  fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
  *
- * Revision 1.24  2002/04/10 16:59:54  warmerda
- * added SHPRewindObject
+ * Revision 1.50  2011-05-13 17:35:17  fwarmerdam
+ * added DBFReorderFields() and DBFAlterFields() functions (from Even)
  *
- * Revision 1.23  2002/01/15 14:36:07  warmerda
- * updated email address
+ * Revision 1.49  2011-04-16 14:38:21  fwarmerdam
+ * avoid warnings with gcc on SHP_CVSID
  *
- * Revision 1.22  2002/01/15 14:32:00  warmerda
- * try to improve SHPAPI_CALL docs
+ * Revision 1.48  2010-08-27 23:42:52  fwarmerdam
+ * add SHPAPI_CALL attribute in code
  *
- * Revision 1.21  2001/11/01 16:29:55  warmerda
- * move pabyRec into SHPInfo for thread safety
+ * Revision 1.47  2010-01-28 11:34:34  fwarmerdam
+ * handle the shape file length limits more gracefully (#3236)
  *
- * Revision 1.20  2001/07/20 13:06:02  warmerda
- * fixed SHPAPI attribute for SHPTreeFindLikelyShapes
+ * Revision 1.46  2008-11-12 14:28:15  fwarmerdam
+ * DBFCreateField() now works on files with records
  *
- * Revision 1.19  2001/05/31 19:20:13  warmerda
- * added DBFGetFieldIndex()
+ * Revision 1.45  2008/11/11 17:47:10  fwarmerdam
+ * added DBFDeleteField() function
  *
- * Revision 1.18  2001/05/31 18:15:40  warmerda
- * Added support for NULL fields in DBF files
+ * Revision 1.44  2008/01/16 20:05:19  bram
+ * Add file hooks that accept UTF-8 encoded filenames on some platforms.  Use SASetupUtf8Hooks
+ *  tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability.  Currently, this
+ *  is only available on the Windows platform that decodes the UTF-8 filenames to wide
+ *  character strings and feeds them to _wfopen and _wremove.
  *
- * Revision 1.17  2001/05/23 13:36:52  warmerda
- * added use of SHPAPI_CALL
+ * Revision 1.43  2008/01/10 16:35:30  fwarmerdam
+ * avoid _ prefix on #defined symbols (bug 1840)
  *
- * Revision 1.16  2000/09/25 14:15:59  warmerda
- * added DBFGetNativeFieldType()
+ * Revision 1.42  2007/12/18 18:28:14  bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
  *
- * Revision 1.15  2000/02/16 16:03:51  warmerda
- * added null shape support
+ * Revision 1.41  2007/12/15 20:25:32  bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function.  This is 
+ * either the number from the LDID header field ("LDID/<number>") or as the 
+ * content of an accompanying .CPG file.  When creating a DBF file, the code can
+ * be set using DBFCreateEx.
  *
- * Revision 1.14  1999/11/05 14:12:05  warmerda
- * updated license terms
+ * Revision 1.40  2007/12/06 07:00:25  fwarmerdam
+ * dbfopen now using SAHooks for fileio
  *
- * Revision 1.13  1999/06/02 18:24:21  warmerda
- * added trimming code
+ * Revision 1.39  2007/12/04 20:37:56  fwarmerdam
+ * preliminary implementation of hooks api for io and errors
  *
- * Revision 1.12  1999/06/02 17:56:12  warmerda
- * added quad'' subnode support for trees
+ * Revision 1.38  2007/11/21 22:39:56  fwarmerdam
+ * close shx file in readonly mode (GDAL #1956)
  *
- * Revision 1.11  1999/05/18 19:11:11  warmerda
- * Added example searching capability
+ * Revision 1.37  2007/10/27 03:31:14  fwarmerdam
+ * limit default depth of tree to 12 levels (gdal ticket #1594)
  *
- * Revision 1.10  1999/05/18 17:49:38  warmerda
- * added initial quadtree support
+ * Revision 1.36  2007/09/10 23:33:15  fwarmerdam
+ * Upstreamed support for visibility flag in SHPAPI_CALL for the needs
+ * of GDAL (gdal ticket #1810).
  *
- * Revision 1.9  1999/05/11 03:19:28  warmerda
- * added new Tuple api, and improved extension handling - add from candrsn
+ * Revision 1.35  2007/09/03 19:48:10  fwarmerdam
+ * move DBFReadAttribute() static dDoubleField into dbfinfo
  *
- * Revision 1.8  1999/03/23 17:22:27  warmerda
- * Added extern "C" protection for C++ users of shapefil.h.
+ * Revision 1.34  2006/06/17 15:33:32  fwarmerdam
+ * added pszWorkField - bug 1202 (rso)
  *
- * Revision 1.7  1998/12/31 15:31:07  warmerda
- * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options.
+ * Revision 1.33  2006/02/15 01:14:30  fwarmerdam
+ * added DBFAddNativeFieldType
  *
- * Revision 1.6  1998/12/03 15:48:15  warmerda
- * Added SHPCalculateExtents().
+ * Revision 1.32  2006/01/26 15:07:32  fwarmerdam
+ * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
  *
- * Revision 1.5  1998/11/09 20:57:16  warmerda
- * Altered SHPGetInfo() call.
+ * Revision 1.31  2006/01/05 01:27:27  fwarmerdam
+ * added dbf deletion mark/fetch
  *
- * Revision 1.4  1998/11/09 20:19:33  warmerda
- * Added 3D support, and use of SHPObject.
+ * Revision 1.30  2005/01/03 22:30:13  fwarmerdam
+ * added support for saved quadtrees
  *
- * Revision 1.3  1995/08/23 02:24:05  warmerda
- * Added support for reading bounds.
+ * Revision 1.29  2004/09/26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
+ * Revision 1.28  2003/12/29 06:02:18  fwarmerdam
+ * added cpl_error.h option
+ *
+ * Revision 1.27  2003/04/21 18:30:37  warmerda
+ * added header write/update public methods
+ *
+ * Revision 1.26  2002/09/29 00:00:08  warmerda
+ * added FTLogical and logical attribute read/write calls
+ *
+ * Revision 1.25  2002/05/07 13:46:30  warmerda
+ * added DBFWriteAttributeDirectly().
+ *
+ * Revision 1.24  2002/04/10 16:59:54  warmerda
+ * added SHPRewindObject
  *
- * Revision 1.2  1995/08/04  03:17:39  warmerda
- * Added header.
+ * Revision 1.23  2002/01/15 14:36:07  warmerda
+ * updated email address
  *
+ * Revision 1.22  2002/01/15 14:32:00  warmerda
+ * try to improve SHPAPI_CALL docs
  */
 
 #include <stdio.h>
@@ -140,7 +166,7 @@ extern "C" {
 /*      is disabled.                                                    */
 /* -------------------------------------------------------------------- */
 #define DISABLE_MULTIPATCH_MEASURE
-
+    
 /* -------------------------------------------------------------------- */
 /*      SHPAPI_CALL                                                     */
 /*                                                                      */
@@ -176,29 +202,88 @@ extern "C" {
 #endif
 
 #ifndef SHPAPI_CALL
-#  define SHPAPI_CALL
+#  if defined(USE_GCC_VISIBILITY_FLAG)
+#    define SHPAPI_CALL     __attribute__ ((visibility("default")))
+#    define SHPAPI_CALL1(x) __attribute__ ((visibility("default")))     x
+#  else
+#    define SHPAPI_CALL
+#  endif
 #endif
 
 #ifndef SHPAPI_CALL1
 #  define SHPAPI_CALL1(x)      x SHPAPI_CALL
 #endif
     
+/* -------------------------------------------------------------------- */
+/*      Macros for controlling CVSID and ensuring they don't appear     */
+/*      as unreferenced variables resulting in lots of warnings.        */
+/* -------------------------------------------------------------------- */
+#ifndef DISABLE_CVSID
+#  if defined(__GNUC__) && __GNUC__ >= 4
+#    define SHP_CVSID(string)     static char cpl_cvsid[] __attribute__((used)) = string;
+#  else
+#    define SHP_CVSID(string)     static char cpl_cvsid[] = string; \
+static char *cvsid_aw() { return( cvsid_aw() ? ((char *) NULL) : cpl_cvsid ); }
+#  endif
+#else
+#  define SHP_CVSID(string)
+#endif
+
+/* -------------------------------------------------------------------- */
+/*      On some platforms, additional file IO hooks are defined that    */
+/*      UTF-8 encoded filenames Unicode filenames                       */
+/* -------------------------------------------------------------------- */
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+#	define SHPAPI_WINDOWS
+#	define SHPAPI_UTF8_HOOKS
+#endif
+
+/* -------------------------------------------------------------------- */
+/*      IO/Error hook functions.                                        */
+/* -------------------------------------------------------------------- */
+typedef int *SAFile;
+
+#ifndef SAOffset
+typedef unsigned long SAOffset;
+#endif
+
+typedef struct {
+    SAFile     (*FOpen) ( const char *filename, const char *access);
+    SAOffset   (*FRead) ( void *p, SAOffset size, SAOffset nmemb, SAFile file);
+    SAOffset   (*FWrite)( void *p, SAOffset size, SAOffset nmemb, SAFile file);
+    SAOffset   (*FSeek) ( SAFile file, SAOffset offset, int whence );
+    SAOffset   (*FTell) ( SAFile file );
+    int        (*FFlush)( SAFile file );
+    int        (*FClose)( SAFile file );
+    int        (*Remove) ( const char *filename );
+
+    void       (*Error) ( const char *message );
+    double     (*Atof)  ( const char *str );
+} SAHooks;
+
+void SHPAPI_CALL SASetupDefaultHooks( SAHooks *psHooks );
+#ifdef SHPAPI_UTF8_HOOKS
+void SHPAPI_CALL SASetupUtf8Hooks( SAHooks *psHooks );
+#endif
+
 /************************************************************************/
 /*                             SHP Support.                             */
 /************************************************************************/
 typedef	struct
 {
-    FILE        *fpSHP;
-    FILE	*fpSHX;
+    SAHooks sHooks;
+
+    SAFile      fpSHP;
+    SAFile 	fpSHX;
 
     int		nShapeType;				/* SHPT_* */
     
-    int		nFileSize;				/* SHP file */
+    unsigned int 	nFileSize;				/* SHP file */
 
     int         nRecords;
     int		nMaxRecords;
-    int		*panRecOffset;
-    int		*panRecSize;
+    unsigned int		*panRecOffset;
+    unsigned int		*panRecSize;
 
     double	adBoundsMin[4];
     double	adBoundsMax[4];
@@ -271,15 +356,26 @@ typedef struct
     double	dfYMax;
     double	dfZMax;
     double	dfMMax;
+
+    int		bMeasureIsUsed;
 } SHPObject;
 
 /* -------------------------------------------------------------------- */
 /*      SHP API Prototypes                                              */
 /* -------------------------------------------------------------------- */
+
+/* If pszAccess is read-only, the fpSHX field of the returned structure */
+/* will be NULL as it is not necessary to keep the SHX file open */
 SHPHandle SHPAPI_CALL
       SHPOpen( const char * pszShapeFile, const char * pszAccess );
 SHPHandle SHPAPI_CALL
+      SHPOpenLL( const char *pszShapeFile, const char *pszAccess, 
+                 SAHooks *psHooks );
+SHPHandle SHPAPI_CALL
       SHPCreate( const char * pszShapeFile, int nShapeType );
+SHPHandle SHPAPI_CALL
+      SHPCreateLL( const char * pszShapeFile, int nShapeType,
+                   SAHooks *psHooks );
 void SHPAPI_CALL
       SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
                   double * padfMinBound, double * padfMaxBound );
@@ -294,19 +390,22 @@ void SHPAPI_CALL
 void SHPAPI_CALL
       SHPComputeExtents( SHPObject * psObject );
 SHPObject SHPAPI_CALL1(*)
-      SHPCreateObject( int nSHPType, int nShapeId,
-                       int nParts, int * panPartStart, int * panPartType,
-                       int nVertices, double * padfX, double * padfY,
-                       double * padfZ, double * padfM );
+      SHPCreateObject( int nSHPType, int nShapeId, int nParts, 
+                       const int * panPartStart, const int * panPartType,
+                       int nVertices, 
+                       const double * padfX, const double * padfY,
+                       const double * padfZ, const double * padfM );
 SHPObject SHPAPI_CALL1(*)
       SHPCreateSimpleObject( int nSHPType, int nVertices,
-                             double * padfX, double * padfY, double * padfZ );
+                             const double * padfX, 
+                             const double * padfY, 
+                             const double * padfZ );
 
 int SHPAPI_CALL
       SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
 
-void SHPAPI_CALL
-      SHPClose( SHPHandle hSHP );
+void SHPAPI_CALL SHPClose( SHPHandle hSHP );
+void SHPAPI_CALL SHPWriteHeader( SHPHandle hSHP );
 
 const char SHPAPI_CALL1(*)
       SHPTypeName( int nSHPType );
@@ -320,6 +419,9 @@ const char SHPAPI_CALL1(*)
 /* this can be two or four for binary or quad tree */
 #define MAX_SUBNODE	4
 
+/* upper limit of tree levels for automatic estimation */
+#define MAX_DEFAULT_TREE_DEPTH 12
+
 typedef struct shape_tree_node
 {
     /* region covered by this node */
@@ -343,6 +445,7 @@ typedef struct
     
     int		nMaxDepth;
     int		nDimension;
+    int         nTotalCount;
     
     SHPTreeNode	*psRoot;
 } SHPTree;
@@ -355,12 +458,8 @@ void    SHPAPI_CALL
 
 int	SHPAPI_CALL
       SHPWriteTree( SHPTree *hTree, const char * pszFilename );
-SHPTree SHPAPI_CALL
-      SHPReadTree( const char * pszFilename );
 
 int	SHPAPI_CALL
-      SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
-int	SHPAPI_CALL
       SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
 int	SHPAPI_CALL
       SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
@@ -376,12 +475,37 @@ int    SHPAPI_CALL1(*)
 int     SHPAPI_CALL
       SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
 
+int SHPAPI_CALL1(*) 
+SHPSearchDiskTree( FILE *fp, 
+                   double *padfBoundsMin, double *padfBoundsMax,
+                   int *pnShapeCount );
+
+
+typedef struct SHPDiskTreeInfo* SHPTreeDiskHandle;
+
+SHPTreeDiskHandle SHPAPI_CALL
+    SHPOpenDiskTree( const char* pszQIXFilename,
+                     SAHooks *psHooks );
+
+void SHPAPI_CALL
+    SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree );
+
+int SHPAPI_CALL1(*) 
+SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree, 
+                   double *padfBoundsMin, double *padfBoundsMax,
+                   int *pnShapeCount );
+
+int SHPAPI_CALL
+    SHPWriteTreeLL(SHPTree *hTree, const char *pszFilename, SAHooks *psHooks );
+
 /************************************************************************/
 /*                             DBF Support.                             */
 /************************************************************************/
 typedef	struct
 {
-    FILE	*fp;
+    SAHooks sHooks;
+
+    SAFile	fp;
 
     int         nRecords;
 
@@ -398,9 +522,17 @@ typedef	struct
     int		nCurrentRecord;
     int		bCurrentRecordModified;
     char	*pszCurrentRecord;
+
+    int         nWorkFieldLength;
+    char        *pszWorkField;
     
     int		bNoHeader;
     int		bUpdated;
+
+    double      dfDoubleField;
+
+    int         iLanguageDriver;
+    char        *pszCodePage;
 } DBFInfo;
 
 typedef DBFInfo * DBFHandle;
@@ -415,10 +547,18 @@ typedef enum {
 
 #define XBASE_FLDHDR_SZ       32
 
+
 DBFHandle SHPAPI_CALL
       DBFOpen( const char * pszDBFFile, const char * pszAccess );
 DBFHandle SHPAPI_CALL
+      DBFOpenLL( const char * pszDBFFile, const char * pszAccess,
+                 SAHooks *psHooks );
+DBFHandle SHPAPI_CALL
       DBFCreate( const char * pszDBFFile );
+DBFHandle SHPAPI_CALL
+      DBFCreateEx( const char * pszDBFFile, const char * pszCodePage );
+DBFHandle SHPAPI_CALL
+      DBFCreateLL( const char * pszDBFFile, const char * pszCodePage, SAHooks *psHooks );
 
 int	SHPAPI_CALL
       DBFGetFieldCount( DBFHandle psDBF );
@@ -428,6 +568,20 @@ int	SHPAPI_CALL
       DBFAddField( DBFHandle hDBF, const char * pszFieldName,
                    DBFFieldType eType, int nWidth, int nDecimals );
 
+int	SHPAPI_CALL
+      DBFAddNativeFieldType( DBFHandle hDBF, const char * pszFieldName,
+                             char chType, int nWidth, int nDecimals );
+
+int	SHPAPI_CALL
+      DBFDeleteField( DBFHandle hDBF, int iField );
+
+int SHPAPI_CALL
+      DBFReorderFields( DBFHandle psDBF, int* panMap );
+
+int SHPAPI_CALL
+      DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
+                         char chType, int nWidth, int nDecimals );
+
 DBFFieldType SHPAPI_CALL
       DBFGetFieldInfo( DBFHandle psDBF, int iField, 
                        char * pszFieldName, int * pnWidth, int * pnDecimals );
@@ -469,16 +623,25 @@ const char SHPAPI_CALL1(*)
 int SHPAPI_CALL
       DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
 
+int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape );
+int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape, 
+                                      int bIsDeleted );
+
 DBFHandle SHPAPI_CALL
       DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
  
 void	SHPAPI_CALL
       DBFClose( DBFHandle hDBF );
+void    SHPAPI_CALL
+      DBFUpdateHeader( DBFHandle hDBF );
 char    SHPAPI_CALL
       DBFGetNativeFieldType( DBFHandle hDBF, int iField );
 
+const char SHPAPI_CALL1(*)
+      DBFGetCodePage(DBFHandle psDBF );
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* ndef _SHAPEFILE_H_INCLUDED */
+#endif /* ndef SHAPEFILE_H_INCLUDED */
diff --git a/shapelib.def b/shapelib.def
index 01964c4..354c8f0 100644
--- a/shapelib.def
+++ b/shapelib.def
@@ -9,6 +9,7 @@ EXPORTS SHPOpen
 	SHPCreateObject
 	SHPCreateSimpleObject
 	SHPClose
+        SHPWriteHeader
 	SHPTypeName
 	SHPPartTypeName
 	SHPCreateTree
@@ -38,5 +39,8 @@ EXPORTS SHPOpen
 	DBFIsAttributeNULL
 	DBFWriteLogicalAttribute
 	DBFReadLogicalAttribute
-
-
+	DBFUpdateHeader
+	DBFGetNativeFieldType
+	SHPRewindObject
+	DBFIsRecordDeleted
+	DBFMarkRecordDeleted
diff --git a/shapelib.html b/shapelib.html
deleted file mode 100644
index 4372d1d..0000000
--- a/shapelib.html
+++ /dev/null
@@ -1,334 +0,0 @@
-<html>
-<head>
-<title>Shapefile C Library V1.2</title>
-</head>
-
-<body>
-<h1>Shapefile C Library V1.2</h1>
-
-<h2>Purpose</h2>
-
-The Shapefile C Library provides the ability to write simple C programs
-for reading, writing and updating (to a limited extent) ESRI Shapefiles,
-and the associated attribute file (.dbf).<p>
-
-<h2>Manifest</h2>
-
-<ul>
-<li> <b>shapelib.html</b>: This file - general documentation on the 
-Shapefile C Library.<p>
-
-<li> <b><a href="shp_api.html">shp_api.html</a></b>: Documentation 
-for the API for accessing the .shp/.shx files. <p>
-
-<li> <b><a href="dbf_api.html">dbf_api.html</a></b>: Documentation 
-for the API for accessing the .dbf attribute files. <p>
-
-<li> <b>shpopen.c</b>: C code for access to .shp/.shx vertex files.<p>
-
-<li> <b>dbfopen.c</b>: C code for access to .dbf attribute file.<p>
-
-<li> <b>shapefil.h</b>:  Include file defining all the services of dbfopen.c 
-and shpopen.c.<p>
-
-<li> <b>contrib/</b>: A directory of "in progress" contributed programs
-from Carl Anderson.<p>
-
-<li> <b>dbfcreate.c</b>: Simple example program for creating a new .dbf file.
-     <p>
-
-<li> <b>dbfadd.c</b>: 
-	Simple example program for adding a record to a .dbf file.<p>
-
-<li> <b>dbfdump.c</b>: Simple example program for displaying the contents of
-		  a .dbf file.<p>
-
-<li> <b>shpcreate.c</b>: Simple example program for creating a new .shp and 
-.shx file.<p>
-
-<li> <b>shpadd.c</b>: Simple example program for adding a shape to an existing
-		  shape file.<p>
-
-<li> <b>shpdump.c</b>: Simple program for dumping all the vertices in a 
-		shapefile with an indicating of the parts.<p>
-
-<li> <b>shputils.c</b>: Complex contributed program capable of clipping and 
-		  appending
-                  shapefiles as well as a few other things.  Type shputils
-                  after building to get a full usage message.<p>
-
-<li> <b>Makefile</b>: A simple makefile to compile the library and example 
-		  programs.<p>
-
-<li> <b>makeshape.sh</b>: A simple script for running some of the example 
-programs.<p>
-
-<li> <b>shptest.c</b>: A simple test harnass to generate each of the supported
-		  types of shapefiles. <p>
-
-
-<li> <b>shptree.c</b>: Implements a simple quadtree algorithm for fast
-spatial searches of shapefiles.<p>
-
-<li> <b>shptreedump.c</b>: A simple mainly showing information on quad
-trees build using the quad tree api.<p>
-
-<li> <b>stream1.sh</b> - A test script, which should produce stream1.out.  
-Note this will only work if you have the example data downloaded.<p>
-
-<li> <b>stream1.out</b>: Expected output of stream1.sh test script.<p>
-
-<li> <b>stream2.sh</b>: A test script, which should produce stream2.out.<p>
-
-<li> <b>stream2.out</b>: Expected output of stream2.sh test script.<p>
-
-<li> <b>pyshapelib-0.1</b>: Prototype contributed Python bindings.<p>
-
-</ul>
-
-<h2>What is a Shapefile?</h2>
-
-If you don't know, you probably don't need this library.  The Shapefile
-format is a new working and interchange format promulagated by ESRI 
-(http://www.esri.com/) for simple vector data with attributes.  It is
-apparently the only file format that can be edited in ARCView 2/3, and can
-also be exported and imported in Arc/Info.  <p>
-
-An excellent white paper on the shapefile format is available from ESRI,
-but it is .pdf format, so you will need Adobe Acrobat to browse it.<p>
-
-The file format actually consists of three files.<p>
-
-<pre>
-XXX.shp - holds the actual vertices.
-XXX.shx - hold index data pointing to the structures in the .shp file.
-XXX.dbf - holds the attributes in xBase (dBase) format.  
-</pre>
-
-<h2>Release Notes</h2>
-
-To get notification of new releases of Shapelib <i>subscribe</i> to 
-the project at www.freshmeat.net.  This is currently the only reliable
-way of finding out about new releases since there is no shapelib specific
-mailing list.<p>
-
-<b>Release 1.2.10</b>: Added SHPRewindObject() function, and shprewind utility
-program.  Added FTLogical, DBFReadLogicalAttribute() and 
-DBFWriteLogicalAttribute() (thanks to Olek Neyman). <p>
-
-<b>Release 1.2.9</b>: Good support for reading and writing NULL fields 
-in .dbf files, good support for NULL shapes and addition of the
-DBFGetFieldIndex() functions (all contributed by Jim Matthews).<p>
-
-An upgraded shputils.c has been contributed by Bill Miller.  Daniel 
-Morissette contributed DBFGetNativeFieldType().  Better error checking
-for disk errors in dbfopen.c.  Various other bug fixes and safety improvements.
-<p>
-
-<b>Release 1.2.8</b>: Added hacked libtool support (supplied by Jan)
-and "rpm ready" install logic.<p>
-
-<b>Release 1.2.7</b>: Fix record size (was 4 bytes too long).  Modify 
-SHPReadObject() to handle null shapes properly.  Use atof() instead of
-sscanf().  Support .DBF as well as .dbf.<p>
-
-<b>Release 1.2.6</b>: Now available under old MIT style license, or at the
-users option, LGPL.  Added the contrib directory of stuff from Carl Anderson
-and the shptree.c API for quadtree based spatial searches.<p>
-
-<b>Release 1.2.5</b>: SHPOpen() now forcably uses "rb" or "r+b" access string
-to avoid common mistakes on Windows.  Also fixed a serious bug with .dbf
-files with a 'F' field type.<p>
-
-<b>Release 1.2.4</b>: DBFOpen() will now automatically translate a .shp
-extension to .dbf for convenience.  SHPOpen() will try datasets with lower
-and uppercase extension.  DBFAddField() now returns the field number,
-not TRUE/FALSE.<p>
-
-<b>Release 1.2.3</b>: Disable writing measures to multi-patches as ArcView
-seems to puke on them (as reported by Monika Sester).  Add white space 
-trimming, and string/numeric attribute interchangability in DBF API
-as suggested by Steve Lime.  Dbfdump was updated to include several 
-reporting options.<p>
-
-<b>Release 1.2.2</b>: Added proper support for multipatch (reading and 
-writing) - this release just for testing purposes.<p>
-
-<b>Release 1.2</b> is mostly a rewrite of the .shp/.shx access API to account 
-for ArcView 3.x 3D shapes, and to encapsulate the shapes in a structure.  
-Existing code using the shapefile library will require substantial changes
-to use release 1.2.<p>
-
-<b>Release V1.1</b> has been built on a number of platforms, and used by a 
-number of people successfully.  V1.1 is the first release with the xBase API 
-documentation.<p>
-
-
-<h2>Maintainer</h2>
-
-This library is maintained by me (Frank Warmerdam) on my own time.  Please 
-send me bug patches and suggestions for the library.  Email can be sent to 
-warmerdam at pobox.com.<p>
-
-The current status of the Shapelib code can be found at
-<a href="http://pobox.com/~warmerdam/root/projects/shapelib/">
-http://pobox.com/~warmerdam/root/projects/shapelib/</a>.  To find out about 
-new releases of Shapelib, select the "Subscribe to new releases" option 
-from the link at 
-<a href="http://freshmeat.net/projects/shapelib/">Freshmeat</a>.<p>
-
-The shputils.c module was contributed by Bill Miller (NC-DOT) who can be
-reached at bmiller at doh.dot.state.nc.us.  I had to modify it substantially
-to work with the 1.2 API, and I am not sure that it works as well as it
-did when it was originally provided by Bill.<p>
-
-<h2>Credits</h2>
-
-I didn't start this section anywhere near soon enough, so alot of earlier
-contributors to Shapelib are lost in pre-history.
-
-<ul>
-<li> Bill Miller (NY-DOT) for shputils.c
-<li> Carl Anderson for the contents of the contrib directory, and 
-the "tuple" additions to dbfopen.c.
-<li> Andrea Giacomelli for patches for dbfopen.c.
-<li> Doug Matthews for portability improvements.
-<li> Jan-Oliver Wagner for convincing me to make it available under LGPL,
-shared library support, and various other patches.
-<li> Dennis Christopher (of Avenza) for testing and bug fixes.
-<li> Miko Syrjä (of 3D-system Oy) for a record size bug fix.
-<li> Steven Lime and Curtis Hill for help with NULL shapes.
-<li> Jim Matthews for support of NULL attributes in dbf files.
-<li> <a href="http://www.pcigeomatics.com/">PCI Geomatics</a> who let me
-release a modified version of their shapefile code in the beginning and
-who hosted shapelib for years.
-</ul>
-
-<h2>In Memorium</h2>
-
-I would like to dedicate Shapelib to the memory of Sol Katz.  While I never
-met him in person, his generous contributions to the GIS community took 
-many forms, including free distribution of a variety of GIS translators
-with source.  The fact that he used this Shapelib in some of his utilities, 
-and thanked me was a great encouragement to me.  I hope I can do his memory 
-honour by trying to contribute in a similar fashion.<p>
-
-<h2>Portability</h2>
-
-The Shapefile C Library should port easily to 32bit systems with ANSI C
-compilers.  It should work on 64 bit architectures (such as the DEC AXP).<p>
-
-Care should also be taken to pass the binary access flag into SHPOpen()
-and DBFOpen() when operating on systems with special text file translation
-such as MSDOS.<p>
-
-The shputils.c module is contributed, and may not take the same approach
-to portability as the rest of the package.<p>
-
-On Linux, and most unix systems it should be possible to build and 
-install shapefile support as a shared library using the "lib" and "lib_install"
-targets of the Makefile.  Note that this Makefile doesn't use autoconf
-mechanisms and will generally require some hand tailoring for your environment.
-
-<h2>Limitations</h2>
-
-<ul>
-
-<li> You can't modify the vertices of existing structures (though you 
-   can update the attributes of existing structures, and create new 
-   structures).<p>
-
-<li> Not written in such a way as to be particularly fast.  This is 
-particularly true of the 1.2 API.  For applications more concerned with
-speed it may be worth using the V1.1 API.<p>
-
-<li> Doesn't set the last access time properly in the .dbf files.<p>
-
-<li> There is no way to synchronize information to the file except to close it.
-<p>
-
-<li> Poor error checking and reporting.<p>
-
-<li> Not professionally supported (well it can be, if you want to pay).<p>
-
-<li> Some aspects of xBase files not supported, though I believe they are
-not used by ESRI.<p>
-
-<li> The application must keep the .dbf file in sync with the .shp/.shx
-files through appropriate use of the DBF and SHP APIs.<p>
-
-<li> No support for the undocumented .sbn/.sbx spatial index files.<p>
-
-</ul>
-
-<h2>Copyright</h2>
-
-The source for the Shapefile C Library is (c) 1998 Frank Warmerdam, 
-and released under the following conditions.  The intent is that anyone
-can do anything with the code, but that I do not assume any liability, nor
-express any warranty for this code.  <p>
-
-As of Shapelib 1.2.6 the core portions of the library are made available
-under two possible licenses.  The licensee can choose to use the code
-under either the Library GNU Public License (LGPL) described in 
-LICENSE.LGPL or under the following MIT style license.  Any files in
-the Shapelib distribution without explicit copyright license terms
-(such as this documentation, the Makefile and so forth) should be
-considered to have the following licensing terms.  Some auxilary portions
-of Shapelib, notably some of the components in the contrib directory
-come under slightly different license restrictions.  Check the source
-files that you are actually using for conditions.<p>
-
-<h3>Default License Terms</h3>
-
-<quote>
-Copyright (c) 1999, Frank Warmerdam<p>
-
-This software is available under the following "MIT Style" license,
-or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
-option is discussed in more detail in shapelib.html.<p>
- 
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:<p>
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.<p>
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.<p>
-</quote>
-
-<h3>Shapelib Modifications</h3>
-
-I am pleased to receive bug fixes, and improvements for Shapelib.  Unless
-the submissions indicate otherwise I will assume that changes submitted to
-me remain under the the above "dual license" terms.  If changes are made
-to the library with the intention that those changes should be protected by
-the LGPL then I should be informed upon submission.  Note that I will not
-generally incorporate changes into the core of Shapelib that are protected 
-under the LGPL as this would effectively limit the whole file and 
-distribution to LGPL terms.<p>
-
-<h3>Opting for LGPL</h3>
-
-For licensee's opting to use Shapelib under LGPL as opposed to the MIT
-Style license above, and wishing to redistribute the software based on 
-Shapelib, I would ask that all "dual license" modules be updated to
-indicate that only the LGPL (and not the MIT Style license) applies.  This
-action represents opting for the LGPL, and thereafter LGPL terms apply to
-any redistribution and modification of the affected modules.<p>
-
-</body>
-</html>
-
-
-
diff --git a/shpadd.c b/shpadd.c
index 68b0c9d..7b20b8a 100644
--- a/shpadd.c
+++ b/shpadd.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shpadd.c,v 1.13 2002/01/15 14:36:07 warmerda Exp $
+ * $Id: shpadd.c,v 1.16 2010-06-21 20:41:52 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Sample application for adding a shape to a shapefile.
@@ -34,6 +34,15 @@
  ******************************************************************************
  *
  * $Log: shpadd.c,v $
+ * Revision 1.16  2010-06-21 20:41:52  fwarmerdam
+ * reformat white space
+ *
+ * Revision 1.15  2007-12-30 16:57:32  fwarmerdam
+ * add support for z and m
+ *
+ * Revision 1.14  2004/09/26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
  * Revision 1.13  2002/01/15 14:36:07  warmerda
  * updated email address
  *
@@ -72,44 +81,68 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shpadd.c,v 1.13 2002/01/15 14:36:07 warmerda Exp $";
-
 #include <stdlib.h>
 #include <string.h>
 #include "shapefil.h"
 
+SHP_CVSID("$Id: shpadd.c,v 1.16 2010-06-21 20:41:52 fwarmerdam Exp $")
+
 int main( int argc, char ** argv )
 
 {
     SHPHandle	hSHP;
     int		nShapeType, nVertices, nParts, *panParts, i, nVMax;
-    double	*padfX, *padfY;
+    double	*padfX, *padfY, *padfZ = NULL, *padfM = NULL;
     SHPObject	*psObject;
+    const char  *tuple = "";
+    const char  *filename;
 
 /* -------------------------------------------------------------------- */
 /*      Display a usage message.                                        */
 /* -------------------------------------------------------------------- */
     if( argc < 2 )
     {
-	printf( "shpadd shp_file [[x y] [+]]*\n" );
-	exit( 1 );
+        printf( "shpadd shp_file [[x y] [+]]*\n" );
+        printf( "  or\n" );
+        printf( "shpadd shp_file -m [[x y m] [+]]*\n" );
+        printf( "  or\n" );
+        printf( "shpadd shp_file -z [[x y z] [+]]*\n" );
+        printf( "  or\n" );
+        printf( "shpadd shp_file -zm [[x y z m] [+]]*\n" );
+        exit( 1 );
+    }
+
+    filename = argv[1];
+    argv++;
+    argc--;
+
+/* -------------------------------------------------------------------- */
+/*      Check for tuple description options.                            */
+/* -------------------------------------------------------------------- */
+    if( argc > 1 
+        && (strcmp(argv[1],"-z") == 0 
+            || strcmp(argv[1],"-m") == 0 
+            || strcmp(argv[1],"-zm") == 0) )
+    {
+        tuple = argv[1] + 1;
+        argv++;
+        argc--;
     }
 
 /* -------------------------------------------------------------------- */
 /*      Open the passed shapefile.                                      */
 /* -------------------------------------------------------------------- */
-    hSHP = SHPOpen( argv[1], "r+b" );
+    hSHP = SHPOpen( filename, "r+b" );
 
     if( hSHP == NULL )
     {
-	printf( "Unable to open:%s\n", argv[1] );
-	exit( 1 );
+        printf( "Unable to open:%s\n", filename );
+        exit( 1 );
     }
 
     SHPGetInfo( hSHP, NULL, &nShapeType, NULL, NULL );
 
-    if( argc == 2 )
+    if( argc == 1 )
         nShapeType = SHPT_NULL;
 
 /* -------------------------------------------------------------------- */
@@ -118,6 +151,11 @@ int main( int argc, char ** argv )
     nVMax = 1000;
     padfX = (double *) malloc(sizeof(double) * nVMax);
     padfY = (double *) malloc(sizeof(double) * nVMax);
+
+    if( strchr(tuple,'z') )
+        padfZ = (double *) malloc(sizeof(double) * nVMax);
+    if( strchr(tuple,'m') )
+        padfM = (double *) malloc(sizeof(double) * nVMax);
     
     nVertices = 0;
 
@@ -130,34 +168,42 @@ int main( int argc, char ** argv )
     nParts = 1;
     panParts[0] = 0;
 
-    for( i = 2; i < argc;  )
+    for( i = 1; i < argc;  )
     {
-	if( argv[i][0] == '+' )
-	{
-	    panParts[nParts++] = nVertices;
-	    i++;
-	}
-	else if( i < argc-1 )
-	{
+        if( argv[i][0] == '+' )
+        {
+            panParts[nParts++] = nVertices;
+            i++;
+        }
+        else if( i < argc-1-strlen(tuple) )
+        {
             if( nVertices == nVMax )
             {
                 nVMax = nVMax * 2;
                 padfX = (double *) realloc(padfX,sizeof(double)*nVMax);
                 padfY = (double *) realloc(padfY,sizeof(double)*nVMax);
+                if( padfZ )
+                    padfZ = (double *) realloc(padfZ,sizeof(double)*nVMax);
+                if( padfM )
+                    padfM = (double *) realloc(padfM,sizeof(double)*nVMax);
             }
 
-	    sscanf( argv[i], "%lg", padfX+nVertices );
-	    sscanf( argv[i+1], "%lg", padfY+nVertices );
-	    nVertices += 1;
-	    i += 2;
-	}
+            sscanf( argv[i++], "%lg", padfX+nVertices );
+            sscanf( argv[i++], "%lg", padfY+nVertices );
+            if( padfZ )
+                sscanf( argv[i++], "%lg", padfZ+nVertices );
+            if( padfM )
+                sscanf( argv[i++], "%lg", padfM+nVertices );
+                
+            nVertices += 1;
+        }
     }
 
 /* -------------------------------------------------------------------- */
 /*      Write the new entity to the shape file.                         */
 /* -------------------------------------------------------------------- */
     psObject = SHPCreateObject( nShapeType, -1, nParts, panParts, NULL,
-                                nVertices, padfX, padfY, NULL, NULL );
+                                nVertices, padfX, padfY, padfZ, padfM );
     SHPWriteObject( hSHP, -1, psObject );
     SHPDestroyObject( psObject );
     
@@ -166,6 +212,8 @@ int main( int argc, char ** argv )
     free( panParts );
     free( padfX );
     free( padfY );
+    free( padfZ );
+    free( padfM );
 
     return 0;
 }
diff --git a/shpcreate.c b/shpcreate.c
index c33dd25..5e170b7 100644
--- a/shpcreate.c
+++ b/shpcreate.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shpcreate.c,v 1.5 2002/01/15 14:36:07 warmerda Exp $
+ * $Id: shpcreate.c,v 1.8 2007-12-30 16:57:33 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Sample application for creating a new shapefile.
@@ -34,6 +34,15 @@
  ******************************************************************************
  *
  * $Log: shpcreate.c,v $
+ * Revision 1.8  2007-12-30 16:57:33  fwarmerdam
+ * add support for z and m
+ *
+ * Revision 1.7  2004/09/26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
+ * Revision 1.6  2004/01/09 16:39:49  fwarmerdam
+ * include standard include files
+ *
  * Revision 1.5  2002/01/15 14:36:07  warmerda
  * updated email address
  *
@@ -48,11 +57,12 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shpcreate.c,v 1.5 2002/01/15 14:36:07 warmerda Exp $";
-
+#include <string.h>
+#include <stdlib.h>
 #include "shapefil.h"
 
+SHP_CVSID("$Id: shpcreate.c,v 1.8 2007-12-30 16:57:33 fwarmerdam Exp $")
+
 int main( int argc, char ** argv )
 
 {
@@ -64,7 +74,7 @@ int main( int argc, char ** argv )
 /* -------------------------------------------------------------------- */
     if( argc != 3 )
     {
-	printf( "shpcreate shp_file [point/arc/polygon/multipoint]\n" );
+	printf( "shpcreate shp_file [point/arc/polygon/multipoint][/m/z]\n" );
 	exit( 1 );
     }
 
@@ -79,6 +89,24 @@ int main( int argc, char ** argv )
         nShapeType = SHPT_POLYGON;
     else if( strcmp(argv[2],"MULTIPOINT")==0 ||strcmp(argv[2],"multipoint")==0)
         nShapeType = SHPT_MULTIPOINT;
+    else if( strcmp(argv[2],"POINTZ") == 0 || strcmp(argv[2],"pointz") == 0 )
+        nShapeType = SHPT_POINTZ;
+    else if( strcmp(argv[2],"ARCZ") == 0 || strcmp(argv[2],"arcz") == 0 )
+        nShapeType = SHPT_ARCZ;
+    else if( strcmp(argv[2],"POLYGONZ") == 0 || strcmp(argv[2],"polygonz") == 0)
+        nShapeType = SHPT_POLYGONZ;
+    else if( strcmp(argv[2],"MULTIPOINTZ") == 0 
+             || strcmp(argv[2],"multipointz") == 0)
+        nShapeType = SHPT_MULTIPOINTZ;
+    else if( strcmp(argv[2],"POINTM") == 0 || strcmp(argv[2],"pointm") == 0 )
+        nShapeType = SHPT_POINTM;
+    else if( strcmp(argv[2],"ARCM") == 0 || strcmp(argv[2],"arcm") == 0 )
+        nShapeType = SHPT_ARCM;
+    else if( strcmp(argv[2],"POLYGONM") == 0 || strcmp(argv[2],"polygonm") == 0)
+        nShapeType = SHPT_POLYGONM;
+    else if( strcmp(argv[2],"MULTIPOINTM") == 0 
+             || strcmp(argv[2],"multipointm") == 0 )
+        nShapeType = SHPT_MULTIPOINTM;
     else
     {
 	printf( "Shape Type `%s' not recognised.\n", argv[2] );
diff --git a/shpdump.c b/shpdump.c
index 5dc1cfa..87dfa49 100644
--- a/shpdump.c
+++ b/shpdump.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $
+ * $Id: shpdump.c,v 1.18 2011-07-24 03:05:14 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Sample application for dumping contents of a shapefile to 
@@ -35,6 +35,30 @@
  ******************************************************************************
  *
  * $Log: shpdump.c,v $
+ * Revision 1.18  2011-07-24 03:05:14  fwarmerdam
+ * use %.15g for formatting coordiantes in shpdump
+ *
+ * Revision 1.17  2010-07-01 07:33:04  fwarmerdam
+ * do not crash in shpdump if null object returned
+ *
+ * Revision 1.16  2010-07-01 07:27:13  fwarmerdam
+ * white space formatting adjustments
+ *
+ * Revision 1.15  2006-01-26 15:07:32  fwarmerdam
+ * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
+ *
+ * Revision 1.14  2005/02/11 17:17:46  fwarmerdam
+ * added panPartStart[0] validation
+ *
+ * Revision 1.13  2004/09/26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
+ * Revision 1.12  2004/01/27 18:05:35  fwarmerdam
+ * Added the -ho (header only) switch.
+ *
+ * Revision 1.11  2004/01/09 16:39:49  fwarmerdam
+ * include standard include files
+ *
  * Revision 1.10  2002/04/10 16:59:29  warmerda
  * added -validate switch
  *
@@ -64,16 +88,18 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $";
-
+#include <string.h>
+#include <stdlib.h>
 #include "shapefil.h"
 
+SHP_CVSID("$Id: shpdump.c,v 1.18 2011-07-24 03:05:14 fwarmerdam Exp $")
+
 int main( int argc, char ** argv )
 
 {
     SHPHandle	hSHP;
     int		nShapeType, nEntities, i, iPart, bValidate = 0,nInvalidCount=0;
+    int         bHeaderOnly = 0;
     const char 	*pszPlus;
     double 	adfMinBound[4], adfMaxBound[4];
 
@@ -84,13 +110,20 @@ int main( int argc, char ** argv )
         argc--;
     }
 
+    if( argc > 1 && strcmp(argv[1],"-ho") == 0 )
+    {
+        bHeaderOnly = 1;
+        argv++;
+        argc--;
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Display a usage message.                                        */
 /* -------------------------------------------------------------------- */
     if( argc != 2 )
     {
-	printf( "shpdump [-validate] shp_file\n" );
-	exit( 1 );
+        printf( "shpdump [-validate] [-ho] shp_file\n" );
+        exit( 1 );
     }
 
 /* -------------------------------------------------------------------- */
@@ -100,8 +133,8 @@ int main( int argc, char ** argv )
 
     if( hSHP == NULL )
     {
-	printf( "Unable to open:%s\n", argv[1] );
-	exit( 1 );
+        printf( "Unable to open:%s\n", argv[1] );
+        exit( 1 );
     }
 
 /* -------------------------------------------------------------------- */
@@ -112,8 +145,8 @@ int main( int argc, char ** argv )
     printf( "Shapefile Type: %s   # of Shapes: %d\n\n",
             SHPTypeName( nShapeType ), nEntities );
     
-    printf( "File Bounds: (%12.3f,%12.3f,%g,%g)\n"
-            "         to  (%12.3f,%12.3f,%g,%g)\n",
+    printf( "File Bounds: (%.15g,%.15g,%.15g,%.15g)\n"
+            "         to  (%.15g,%.15g,%.15g,%.15g)\n",
             adfMinBound[0], 
             adfMinBound[1], 
             adfMinBound[2], 
@@ -122,52 +155,85 @@ int main( int argc, char ** argv )
             adfMaxBound[1], 
             adfMaxBound[2], 
             adfMaxBound[3] );
-    
+
 /* -------------------------------------------------------------------- */
 /*	Skim over the list of shapes, printing all the vertices.	*/
 /* -------------------------------------------------------------------- */
-    for( i = 0; i < nEntities; i++ )
+    for( i = 0; i < nEntities && !bHeaderOnly; i++ )
     {
-	int		j;
+        int		j;
         SHPObject	*psShape;
 
-	psShape = SHPReadObject( hSHP, i );
+        psShape = SHPReadObject( hSHP, i );
+
+        if( psShape == NULL )
+        {
+            fprintf( stderr,
+                     "Unable to read shape %d, terminating object reading.\n",
+                    i );
+            break;
+        }
+
+        if( psShape->bMeasureIsUsed )
+            printf( "\nShape:%d (%s)  nVertices=%d, nParts=%d\n"
+                    "  Bounds:(%.15g,%.15g, %.15g, %.15g)\n"
+                    "      to (%.15g,%.15g, %.15g, %.15g)\n",
+                    i, SHPTypeName(psShape->nSHPType),
+                    psShape->nVertices, psShape->nParts,
+                    psShape->dfXMin, psShape->dfYMin,
+                    psShape->dfZMin, psShape->dfMMin,
+                    psShape->dfXMax, psShape->dfYMax,
+                    psShape->dfZMax, psShape->dfMMax );
+        else
+            printf( "\nShape:%d (%s)  nVertices=%d, nParts=%d\n"
+                    "  Bounds:(%.15g,%.15g, %.15g)\n"
+                    "      to (%.15g,%.15g, %.15g)\n",
+                    i, SHPTypeName(psShape->nSHPType),
+                    psShape->nVertices, psShape->nParts,
+                    psShape->dfXMin, psShape->dfYMin,
+                    psShape->dfZMin,
+                    psShape->dfXMax, psShape->dfYMax,
+                    psShape->dfZMax );
 
-	printf( "\nShape:%d (%s)  nVertices=%d, nParts=%d\n"
-                "  Bounds:(%12.3f,%12.3f, %g, %g)\n"
-                "      to (%12.3f,%12.3f, %g, %g)\n",
-	        i, SHPTypeName(psShape->nSHPType),
-                psShape->nVertices, psShape->nParts,
-                psShape->dfXMin, psShape->dfYMin,
-                psShape->dfZMin, psShape->dfMMin,
-                psShape->dfXMax, psShape->dfYMax,
-                psShape->dfZMax, psShape->dfMMax );
+        if( psShape->nParts > 0 && psShape->panPartStart[0] != 0 )
+        {
+            fprintf( stderr, "panPartStart[0] = %d, not zero as expected.\n",
+                     psShape->panPartStart[0] );
+        }
 
-	for( j = 0, iPart = 1; j < psShape->nVertices; j++ )
-	{
+        for( j = 0, iPart = 1; j < psShape->nVertices; j++ )
+        {
             const char	*pszPartType = "";
 
             if( j == 0 && psShape->nParts > 0 )
                 pszPartType = SHPPartTypeName( psShape->panPartType[0] );
             
-	    if( iPart < psShape->nParts
+            if( iPart < psShape->nParts
                 && psShape->panPartStart[iPart] == j )
-	    {
+            {
                 pszPartType = SHPPartTypeName( psShape->panPartType[iPart] );
-		iPart++;
-		pszPlus = "+";
-	    }
-	    else
-	        pszPlus = " ";
-
-	    printf("   %s (%12.3f,%12.3f, %g, %g) %s \n",
-                   pszPlus,
-                   psShape->padfX[j],
-                   psShape->padfY[j],
-                   psShape->padfZ[j],
-                   psShape->padfM[j],
-                   pszPartType );
-	}
+                iPart++;
+                pszPlus = "+";
+            }
+            else
+                pszPlus = " ";
+
+            if( psShape->bMeasureIsUsed )
+                printf("   %s (%.15g,%.15g, %.15g, %.15g) %s \n",
+                       pszPlus,
+                       psShape->padfX[j],
+                       psShape->padfY[j],
+                       psShape->padfZ[j],
+                       psShape->padfM[j],
+                       pszPartType );
+            else
+                printf("   %s (%.15g,%.15g, %.15g) %s \n",
+                       pszPlus,
+                       psShape->padfX[j],
+                       psShape->padfY[j],
+                       psShape->padfZ[j],
+                       pszPartType );
+        }
 
         if( bValidate )
         {
diff --git a/shpopen.c b/shpopen.c
index 6e1d626..ee9fce5 100644
--- a/shpopen.c
+++ b/shpopen.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $
+ * $Id: shpopen.c,v 1.73 2012-01-24 22:33:01 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Implementation of core Shapefile read/write functions.
@@ -34,6 +34,112 @@
  ******************************************************************************
  *
  * $Log: shpopen.c,v $
+ * Revision 1.73  2012-01-24 22:33:01  fwarmerdam
+ * fix memory leak on failure to open .shp (gdal #4410)
+ *
+ * Revision 1.72  2011-12-11 22:45:28  fwarmerdam
+ * fix failure return from SHPOpenLL.
+ *
+ * Revision 1.71  2011-09-15 03:33:58  fwarmerdam
+ * fix missing cast (#2344)
+ *
+ * Revision 1.70  2011-07-24 05:59:25  fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
+ *
+ * Revision 1.69  2011-07-24 03:24:22  fwarmerdam
+ * fix memory leaks in error cases creating shapefiles (#2061)
+ *
+ * Revision 1.68  2010-08-27 23:42:52  fwarmerdam
+ * add SHPAPI_CALL attribute in code
+ *
+ * Revision 1.67  2010-07-01 08:15:48  fwarmerdam
+ * do not error out on an object with zero vertices
+ *
+ * Revision 1.66  2010-07-01 07:58:57  fwarmerdam
+ * minor cleanup of error handling
+ *
+ * Revision 1.65  2010-07-01 07:27:13  fwarmerdam
+ * white space formatting adjustments
+ *
+ * Revision 1.64  2010-01-28 11:34:34  fwarmerdam
+ * handle the shape file length limits more gracefully (#3236)
+ *
+ * Revision 1.63  2010-01-28 04:04:40  fwarmerdam
+ * improve numerical accuracy of SHPRewind() algs (gdal #3363)
+ *
+ * Revision 1.62  2010-01-17 05:34:13  fwarmerdam
+ * Remove asserts on x/y being null (#2148).
+ *
+ * Revision 1.61  2010-01-16 05:07:42  fwarmerdam
+ * allow 0/nulls in shpcreateobject (#2148)
+ *
+ * Revision 1.60  2009-09-17 20:50:02  bram
+ * on Win32, define snprintf as alias to _snprintf
+ *
+ * Revision 1.59  2008-03-14 05:25:31  fwarmerdam
+ * Correct crash on buggy geometries (gdal #2218)
+ *
+ * Revision 1.58  2008/01/08 23:28:26  bram
+ * on line 2095, use a float instead of a double to avoid a compiler warning
+ *
+ * Revision 1.57  2007/12/06 07:00:25  fwarmerdam
+ * dbfopen now using SAHooks for fileio
+ *
+ * Revision 1.56  2007/12/04 20:37:56  fwarmerdam
+ * preliminary implementation of hooks api for io and errors
+ *
+ * Revision 1.55  2007/11/21 22:39:56  fwarmerdam
+ * close shx file in readonly mode (GDAL #1956)
+ *
+ * Revision 1.54  2007/11/15 00:12:47  mloskot
+ * Backported recent changes from GDAL (Ticket #1415) to Shapelib.
+ *
+ * Revision 1.53  2007/11/14 22:31:08  fwarmerdam
+ * checks after mallocs to detect for corrupted/voluntary broken shapefiles.
+ * http://trac.osgeo.org/gdal/ticket/1991
+ *
+ * Revision 1.52  2007/06/21 15:58:33  fwarmerdam
+ * fix for SHPRewindObject when rings touch at one vertex (gdal #976)
+ *
+ * Revision 1.51  2006/09/04 15:24:01  fwarmerdam
+ * Fixed up log message for 1.49.
+ *
+ * Revision 1.50  2006/09/04 15:21:39  fwarmerdam
+ * fix of last fix
+ *
+ * Revision 1.49  2006/09/04 15:21:00  fwarmerdam
+ * MLoskot: Added stronger test of Shapefile reading failures, e.g. truncated
+ * files.  The problem was discovered by Tim Sutton and reported here
+ *   https://svn.qgis.org/trac/ticket/200
+ *
+ * Revision 1.48  2006/01/26 15:07:32  fwarmerdam
+ * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
+ *
+ * Revision 1.47  2006/01/04 20:07:23  fwarmerdam
+ * In SHPWriteObject() make sure that the record length is updated
+ * when rewriting an existing record.
+ *
+ * Revision 1.46  2005/02/11 17:17:46  fwarmerdam
+ * added panPartStart[0] validation
+ *
+ * Revision 1.45  2004/09/26 20:09:48  fwarmerdam
+ * const correctness changes
+ *
+ * Revision 1.44  2003/12/29 00:18:39  fwarmerdam
+ * added error checking for failed IO and optional CPL error reporting
+ *
+ * Revision 1.43  2003/12/01 16:20:08  warmerda
+ * be careful of zero vertex shapes
+ *
+ * Revision 1.42  2003/12/01 14:58:27  warmerda
+ * added degenerate object check in SHPRewindObject()
+ *
+ * Revision 1.41  2003/07/08 15:22:43  warmerda
+ * avoid warning
+ *
+ * Revision 1.40  2003/04/21 18:30:37  warmerda
+ * added header write/update public methods
+ *
  * Revision 1.39  2002/08/26 06:46:56  warmerda
  * avoid c++ comments
  *
@@ -158,9 +264,6 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $";
-
 #include "shapefil.h"
 
 #include <math.h>
@@ -168,13 +271,16 @@ static char rcsid[] =
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdio.h>
+
+SHP_CVSID("$Id: shpopen.c,v 1.73 2012-01-24 22:33:01 fwarmerdam Exp $")
 
 typedef unsigned char uchar;
 
 #if UINT_MAX == 65535
-typedef long	      int32;
+typedef unsigned long	      int32;
 #else
-typedef int	      int32;
+typedef unsigned int	      int32;
 #endif
 
 #ifndef FALSE
@@ -188,6 +294,12 @@ typedef int	      int32;
 #  define MAX(a,b)      ((a>b) ? a : b)
 #endif
 
+#if defined(WIN32) || defined(_WIN32)
+#  ifndef snprintf
+#     define snprintf _snprintf
+#  endif
+#endif
+
 static int 	bBigEndian;
 
 
@@ -234,7 +346,7 @@ static void * SfRealloc( void * pMem, int nNewSize )
 /*	contents of the index (.shx) file.				*/
 /************************************************************************/
 
-static void SHPWriteHeader( SHPHandle psSHP )
+void SHPAPI_CALL SHPWriteHeader( SHPHandle psSHP )
 
 {
     uchar     	abyHeader[100];
@@ -242,12 +354,18 @@ static void SHPWriteHeader( SHPHandle psSHP )
     int32	i32;
     double	dValue;
     int32	*panSHX;
+    
+    if (psSHP->fpSHX == NULL)
+    {
+        psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed");
+        return;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Prepare header block for .shp file.                             */
 /* -------------------------------------------------------------------- */
     for( i = 0; i < 100; i++ )
-      abyHeader[i] = 0;
+        abyHeader[i] = 0;
 
     abyHeader[2] = 0x27;				/* magic cookie */
     abyHeader[3] = 0x0a;
@@ -299,8 +417,12 @@ static void SHPWriteHeader( SHPHandle psSHP )
 /* -------------------------------------------------------------------- */
 /*      Write .shp file header.                                         */
 /* -------------------------------------------------------------------- */
-    fseek( psSHP->fpSHP, 0, 0 );
-    fwrite( abyHeader, 100, 1, psSHP->fpSHP );
+    if( psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 0 ) != 0 
+        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
+    {
+        psSHP->sHooks.Error( "Failure writing .shp header" );
+        return;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Prepare, and write .shx file header.                            */
@@ -309,8 +431,12 @@ static void SHPWriteHeader( SHPHandle psSHP )
     ByteCopy( &i32, abyHeader+24, 4 );
     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
     
-    fseek( psSHP->fpSHX, 0, 0 );
-    fwrite( abyHeader, 100, 1, psSHP->fpSHX );
+    if( psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 0 ) != 0 
+        || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
+    {
+        psSHP->sHooks.Error( "Failure writing .shx header" );
+        return;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Write out the .shx contents.                                    */
@@ -319,15 +445,40 @@ static void SHPWriteHeader( SHPHandle psSHP )
 
     for( i = 0; i < psSHP->nRecords; i++ )
     {
-	panSHX[i*2  ] = psSHP->panRecOffset[i]/2;
-	panSHX[i*2+1] = psSHP->panRecSize[i]/2;
-	if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
-	if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
+        panSHX[i*2  ] = psSHP->panRecOffset[i]/2;
+        panSHX[i*2+1] = psSHP->panRecSize[i]/2;
+        if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
+        if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
     }
 
-    fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX );
+    if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX ) 
+        != psSHP->nRecords )
+    {
+        psSHP->sHooks.Error( "Failure writing .shx contents" );
+    }
 
     free( panSHX );
+
+/* -------------------------------------------------------------------- */
+/*      Flush to disk.                                                  */
+/* -------------------------------------------------------------------- */
+    psSHP->sHooks.FFlush( psSHP->fpSHP );
+    psSHP->sHooks.FFlush( psSHP->fpSHX );
+}
+
+/************************************************************************/
+/*                              SHPOpen()                               */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPOpen( const char * pszLayer, const char * pszAccess )
+
+{
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return SHPOpenLL( pszLayer, pszAccess, &sHooks );
 }
 
 /************************************************************************/
@@ -338,7 +489,7 @@ static void SHPWriteHeader( SHPHandle psSHP )
 /************************************************************************/
    
 SHPHandle SHPAPI_CALL
-SHPOpen( const char * pszLayer, const char * pszAccess )
+SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks )
 
 {
     char		*pszFullname, *pszBasename;
@@ -374,6 +525,7 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
     psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
 
     psSHP->bUpdated = FALSE;
+    memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
 
 /* -------------------------------------------------------------------- */
 /*	Compute the base (layer) name.  If there is any extension	*/
@@ -382,9 +534,9 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
     pszBasename = (char *) malloc(strlen(pszLayer)+5);
     strcpy( pszBasename, pszLayer );
     for( i = strlen(pszBasename)-1; 
-	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-	       && pszBasename[i] != '\\';
-	 i-- ) {}
+         i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+             && pszBasename[i] != '\\';
+         i-- ) {}
 
     if( pszBasename[i] == '.' )
         pszBasename[i] = '\0';
@@ -394,33 +546,46 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
 /*	a PC to Unix with upper case filenames won't work!		*/
 /* -------------------------------------------------------------------- */
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
-    sprintf( pszFullname, "%s.shp", pszBasename );
-    psSHP->fpSHP = fopen(pszFullname, pszAccess );
+    sprintf( pszFullname, "%s.shp", pszBasename ) ;
+    psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
     if( psSHP->fpSHP == NULL )
     {
         sprintf( pszFullname, "%s.SHP", pszBasename );
-        psSHP->fpSHP = fopen(pszFullname, pszAccess );
+        psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
     }
     
     if( psSHP->fpSHP == NULL )
     {
+        char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
+        sprintf( pszMessage, "Unable to open %s.shp or %s.SHP.", 
+                  pszBasename, pszBasename );
+        psHooks->Error( pszMessage );
+        free( pszMessage );
+
         free( psSHP );
         free( pszBasename );
         free( pszFullname );
-        return( NULL );
+
+        return NULL;
     }
 
     sprintf( pszFullname, "%s.shx", pszBasename );
-    psSHP->fpSHX = fopen(pszFullname, pszAccess );
+    psSHP->fpSHX =  psSHP->sHooks.FOpen(pszFullname, pszAccess );
     if( psSHP->fpSHX == NULL )
     {
         sprintf( pszFullname, "%s.SHX", pszBasename );
-        psSHP->fpSHX = fopen(pszFullname, pszAccess );
+        psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
     }
     
     if( psSHP->fpSHX == NULL )
     {
-        fclose( psSHP->fpSHP );
+        char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
+        sprintf( pszMessage, "Unable to open %s.shx or %s.SHX.", 
+                  pszBasename, pszBasename );
+        psHooks->Error( pszMessage );
+        free( pszMessage );
+
+        psSHP->sHooks.FClose( psSHP->fpSHP );
         free( psSHP );
         free( pszBasename );
         free( pszFullname );
@@ -434,44 +599,51 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
 /*  Read the file size from the SHP file.				*/
 /* -------------------------------------------------------------------- */
     pabyBuf = (uchar *) malloc(100);
-    fread( pabyBuf, 100, 1, psSHP->fpSHP );
+    psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
 
-    psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
-			+ pabyBuf[25] * 256 * 256
-			+ pabyBuf[26] * 256
-			+ pabyBuf[27]) * 2;
+    psSHP->nFileSize = ((unsigned int)pabyBuf[24] * 256 * 256 * 256
+                        + (unsigned int)pabyBuf[25] * 256 * 256
+                        + (unsigned int)pabyBuf[26] * 256
+                        + (unsigned int)pabyBuf[27]) * 2;
 
 /* -------------------------------------------------------------------- */
 /*  Read SHX file Header info                                           */
 /* -------------------------------------------------------------------- */
-    fread( pabyBuf, 100, 1, psSHP->fpSHX );
-
-    if( pabyBuf[0] != 0 
+    if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 
+        || pabyBuf[0] != 0 
         || pabyBuf[1] != 0 
         || pabyBuf[2] != 0x27 
         || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
     {
-	fclose( psSHP->fpSHP );
-	fclose( psSHP->fpSHX );
-	free( psSHP );
+        psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
+        psSHP->sHooks.FClose( psSHP->fpSHP );
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+        free( psSHP );
 
-	return( NULL );
+        return( NULL );
     }
 
     psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
-      + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
+        + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
     psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
 
     psSHP->nShapeType = pabyBuf[32];
 
     if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
     {
-        /* this header appears to be corrupt.  Give up. */
-	fclose( psSHP->fpSHP );
-	fclose( psSHP->fpSHX );
-	free( psSHP );
+        char szError[200];
+        
+        sprintf( szError, 
+                 "Record count in .shp header is %d, which seems\n"
+                 "unreasonable.  Assuming header is corrupt.",
+                 psSHP->nRecords );
+        psSHP->sHooks.Error( szError );				       
+        psSHP->sHooks.FClose( psSHP->fpSHP );
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+        free( psSHP );
+        free(pabyBuf);
 
-	return( NULL );
+        return( NULL );
     }
 
 /* -------------------------------------------------------------------- */
@@ -517,26 +689,72 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
 /* -------------------------------------------------------------------- */
     psSHP->nMaxRecords = psSHP->nRecords;
 
-    psSHP->panRecOffset =
-        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
-    psSHP->panRecSize =
-        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
-
+    psSHP->panRecOffset = (unsigned int *)
+        malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
+    psSHP->panRecSize = (unsigned int *)
+        malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
     pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
-    fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX );
+
+    if (psSHP->panRecOffset == NULL ||
+        psSHP->panRecSize == NULL ||
+        pabyBuf == NULL)
+    {
+        char szError[200];
+
+        sprintf(szError, 
+                "Not enough memory to allocate requested memory (nRecords=%d).\n"
+                "Probably broken SHP file", 
+                psSHP->nRecords );
+        psSHP->sHooks.Error( szError );
+        psSHP->sHooks.FClose( psSHP->fpSHP );
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+        if (psSHP->panRecOffset) free( psSHP->panRecOffset );
+        if (psSHP->panRecSize) free( psSHP->panRecSize );
+        if (pabyBuf) free( pabyBuf );
+        free( psSHP );
+        return( NULL );
+    }
+
+    if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) 
+        != psSHP->nRecords )
+    {
+        char szError[200];
+
+        sprintf( szError, 
+                 "Failed to read all values for %d records in .shx file.",
+                 psSHP->nRecords );
+        psSHP->sHooks.Error( szError );
+
+        /* SHX is short or unreadable for some reason. */
+        psSHP->sHooks.FClose( psSHP->fpSHP );
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+        free( psSHP->panRecOffset );
+        free( psSHP->panRecSize );
+        free( pabyBuf );
+        free( psSHP );
+
+        return( NULL );
+    }
+    
+    /* In read-only mode, we can close the SHX now */
+    if (strcmp(pszAccess, "rb") == 0)
+    {
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+        psSHP->fpSHX = NULL;
+    }
 
     for( i = 0; i < psSHP->nRecords; i++ )
     {
-	int32		nOffset, nLength;
+        int32		nOffset, nLength;
 
-	memcpy( &nOffset, pabyBuf + i * 8, 4 );
-	if( !bBigEndian ) SwapWord( 4, &nOffset );
+        memcpy( &nOffset, pabyBuf + i * 8, 4 );
+        if( !bBigEndian ) SwapWord( 4, &nOffset );
 
-	memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
-	if( !bBigEndian ) SwapWord( 4, &nLength );
+        memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
+        if( !bBigEndian ) SwapWord( 4, &nLength );
 
-	psSHP->panRecOffset[i] = nOffset*2;
-	psSHP->panRecSize[i] = nLength*2;
+        psSHP->panRecOffset[i] = nOffset*2;
+        psSHP->panRecSize[i] = nLength*2;
     }
     free( pabyBuf );
 
@@ -553,13 +771,14 @@ void SHPAPI_CALL
 SHPClose(SHPHandle psSHP )
 
 {
+    if( psSHP == NULL )
+        return;
+
 /* -------------------------------------------------------------------- */
 /*	Update the header if we have modified anything.			*/
 /* -------------------------------------------------------------------- */
     if( psSHP->bUpdated )
-    {
 	SHPWriteHeader( psSHP );
-    }
 
 /* -------------------------------------------------------------------- */
 /*      Free all resources, and close files.                            */
@@ -567,8 +786,9 @@ SHPClose(SHPHandle psSHP )
     free( psSHP->panRecOffset );
     free( psSHP->panRecSize );
 
-    fclose( psSHP->fpSHX );
-    fclose( psSHP->fpSHP );
+    if ( psSHP->fpSHX != NULL)
+        psSHP->sHooks.FClose( psSHP->fpSHX );
+    psSHP->sHooks.FClose( psSHP->fpSHP );
 
     if( psSHP->pabyRec != NULL )
     {
@@ -590,6 +810,9 @@ SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
 
 {
     int		i;
+
+    if( psSHP == NULL )
+        return;
     
     if( pnEntities != NULL )
         *pnEntities = psSHP->nRecords;
@@ -617,9 +840,27 @@ SHPHandle SHPAPI_CALL
 SHPCreate( const char * pszLayer, int nShapeType )
 
 {
-    char	*pszBasename, *pszFullname;
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return SHPCreateLL( pszLayer, nShapeType, &sHooks );
+}
+
+/************************************************************************/
+/*                             SHPCreate()                              */
+/*                                                                      */
+/*      Create a new shape file and return a handle to the open         */
+/*      shape file with read/write access.                              */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks )
+
+{
+    char	*pszBasename = NULL, *pszFullname = NULL;
     int		i;
-    FILE	*fpSHP, *fpSHX;
+    SAFile	fpSHP = NULL, fpSHX = NULL;
     uchar     	abyHeader[100];
     int32	i32;
     double	dValue;
@@ -640,9 +881,9 @@ SHPCreate( const char * pszLayer, int nShapeType )
     pszBasename = (char *) malloc(strlen(pszLayer)+5);
     strcpy( pszBasename, pszLayer );
     for( i = strlen(pszBasename)-1; 
-	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
-	       && pszBasename[i] != '\\';
-	 i-- ) {}
+         i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+             && pszBasename[i] != '\\';
+         i-- ) {}
 
     if( pszBasename[i] == '.' )
         pszBasename[i] = '\0';
@@ -652,23 +893,29 @@ SHPCreate( const char * pszLayer, int nShapeType )
 /* -------------------------------------------------------------------- */
     pszFullname = (char *) malloc(strlen(pszBasename) + 5);
     sprintf( pszFullname, "%s.shp", pszBasename );
-    fpSHP = fopen(pszFullname, "wb" );
+    fpSHP = psHooks->FOpen(pszFullname, "wb" );
     if( fpSHP == NULL )
-        return( NULL );
+    {
+        psHooks->Error( "Failed to create file .shp file." );
+        goto error;
+    }
 
     sprintf( pszFullname, "%s.shx", pszBasename );
-    fpSHX = fopen(pszFullname, "wb" );
+    fpSHX = psHooks->FOpen(pszFullname, "wb" );
     if( fpSHX == NULL )
-        return( NULL );
+    {
+        psHooks->Error( "Failed to create file .shx file." );
+        goto error;
+    }
 
-    free( pszFullname );
-    free( pszBasename );
+    free( pszFullname ); pszFullname = NULL;
+    free( pszBasename ); pszBasename = NULL;
 
 /* -------------------------------------------------------------------- */
 /*      Prepare header block for .shp file.                             */
 /* -------------------------------------------------------------------- */
     for( i = 0; i < 100; i++ )
-      abyHeader[i] = 0;
+        abyHeader[i] = 0;
 
     abyHeader[2] = 0x27;				/* magic cookie */
     abyHeader[3] = 0x0a;
@@ -694,7 +941,11 @@ SHPCreate( const char * pszLayer, int nShapeType )
 /* -------------------------------------------------------------------- */
 /*      Write .shp file header.                                         */
 /* -------------------------------------------------------------------- */
-    fwrite( abyHeader, 100, 1, fpSHP );
+    if( psHooks->FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
+    {
+        psHooks->Error( "Failed to write .shp header." );
+        goto error;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Prepare, and write .shx file header.                            */
@@ -703,15 +954,26 @@ SHPCreate( const char * pszLayer, int nShapeType )
     ByteCopy( &i32, abyHeader+24, 4 );
     if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
     
-    fwrite( abyHeader, 100, 1, fpSHX );
+    if( psHooks->FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
+    {
+        psHooks->Error( "Failed to write .shx header." );
+        goto error;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Close the files, and then open them as regular existing files.  */
 /* -------------------------------------------------------------------- */
-    fclose( fpSHP );
-    fclose( fpSHX );
+    psHooks->FClose( fpSHP );
+    psHooks->FClose( fpSHX );
 
-    return( SHPOpen( pszLayer, "r+b" ) );
+    return( SHPOpenLL( pszLayer, "r+b", psHooks ) );
+
+error:
+    if (pszFullname) free(pszFullname);
+    if (pszBasename) free(pszBasename);
+    if (fpSHP) psHooks->FClose( fpSHP );
+    if (fpSHX) psHooks->FClose( fpSHX );
+    return NULL;
 }
 
 /************************************************************************/
@@ -785,9 +1047,9 @@ SHPComputeExtents( SHPObject * psObject )
 
 SHPObject SHPAPI_CALL1(*)
 SHPCreateObject( int nSHPType, int nShapeId, int nParts,
-                 int * panPartStart, int * panPartType,
-                 int nVertices, double * padfX, double * padfY,
-                 double * padfZ, double * padfM )
+                 const int * panPartStart, const int * panPartType,
+                 int nVertices, const double *padfX, const double *padfY,
+                 const double * padfZ, const double * padfM )
 
 {
     SHPObject	*psObject;
@@ -796,6 +1058,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
     psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
     psObject->nSHPType = nSHPType;
     psObject->nShapeId = nShapeId;
+    psObject->bMeasureIsUsed = FALSE;
 
 /* -------------------------------------------------------------------- */
 /*	Establish whether this shape type has M, and Z values.		*/
@@ -835,7 +1098,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
         psObject->nParts = MAX(1,nParts);
 
         psObject->panPartStart = (int *)
-            malloc(sizeof(int) * psObject->nParts);
+            calloc(sizeof(int), psObject->nParts);
         psObject->panPartType = (int *)
             malloc(sizeof(int) * psObject->nParts);
 
@@ -844,17 +1107,21 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
         
         for( i = 0; i < nParts; i++ )
         {
-            psObject->panPartStart[i] = panPartStart[i];
+            if( psObject->panPartStart != NULL )
+                psObject->panPartStart[i] = panPartStart[i];
+
             if( panPartType != NULL )
                 psObject->panPartType[i] = panPartType[i];
             else
                 psObject->panPartType[i] = SHPP_RING;
         }
+
+        if( psObject->panPartStart[0] != 0 )
+            psObject->panPartStart[0] = 0;
     }
 
 /* -------------------------------------------------------------------- */
-/*      Capture vertices.  Note that Z and M are optional, but X and    */
-/*      Y are not.                                                      */
+/*      Capture vertices.  Note that X, Y, Z and M are optional.        */
 /* -------------------------------------------------------------------- */
     if( nVertices > 0 )
     {
@@ -863,18 +1130,19 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
         psObject->padfZ = (double *) calloc(sizeof(double),nVertices);
         psObject->padfM = (double *) calloc(sizeof(double),nVertices);
 
-        assert( padfX != NULL );
-        assert( padfY != NULL );
-    
         for( i = 0; i < nVertices; i++ )
         {
-            psObject->padfX[i] = padfX[i];
-            psObject->padfY[i] = padfY[i];
+            if( padfX != NULL )
+                psObject->padfX[i] = padfX[i];
+            if( padfY != NULL )
+                psObject->padfY[i] = padfY[i];
             if( padfZ != NULL && bHasZ )
                 psObject->padfZ[i] = padfZ[i];
             if( padfM != NULL && bHasM )
                 psObject->padfM[i] = padfM[i];
         }
+        if( padfM != NULL && bHasM )
+            psObject->bMeasureIsUsed = TRUE;
     }
 
 /* -------------------------------------------------------------------- */
@@ -895,8 +1163,8 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
 
 SHPObject SHPAPI_CALL1(*)
 SHPCreateSimpleObject( int nSHPType, int nVertices,
-                       double * padfX, double * padfY,
-                       double * padfZ )
+                       const double * padfX, const double * padfY,
+                       const double * padfZ )
 
 {
     return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
@@ -914,7 +1182,8 @@ int SHPAPI_CALL
 SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
 		      
 {
-    int	       	nRecordOffset, i, nRecordSize;
+    unsigned int	       	nRecordOffset, nRecordSize=0;
+    int i;
     uchar	*pabyRec;
     int32	i32;
 
@@ -943,19 +1212,19 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
 /* -------------------------------------------------------------------- */
     if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
     {
-	psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
+        psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
 
-	psSHP->panRecOffset = (int *) 
-            SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
-	psSHP->panRecSize = (int *) 
-            SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
+        psSHP->panRecOffset = (unsigned int *) 
+            SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * psSHP->nMaxRecords );
+        psSHP->panRecSize = (unsigned int *) 
+            SfRealloc(psSHP->panRecSize,sizeof(unsigned int) * psSHP->nMaxRecords );
     }
 
 /* -------------------------------------------------------------------- */
 /*      Initialize record.                                              */
 /* -------------------------------------------------------------------- */
     pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) 
-			       + psObject->nParts * 8 + 128);
+                               + psObject->nParts * 8 + 128);
     
 /* -------------------------------------------------------------------- */
 /*  Extract vertices for a Polygon or Arc.				*/
@@ -968,32 +1237,32 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
         || psObject->nSHPType == SHPT_ARCM
         || psObject->nSHPType == SHPT_MULTIPATCH )
     {
-	int32		nPoints, nParts;
-	int    		i;
+        int32		nPoints, nParts;
+        int    		i;
 
-	nPoints = psObject->nVertices;
-	nParts = psObject->nParts;
+        nPoints = psObject->nVertices;
+        nParts = psObject->nParts;
 
-	_SHPSetBounds( pabyRec + 12, psObject );
+        _SHPSetBounds( pabyRec + 12, psObject );
 
-	if( bBigEndian ) SwapWord( 4, &nPoints );
-	if( bBigEndian ) SwapWord( 4, &nParts );
+        if( bBigEndian ) SwapWord( 4, &nPoints );
+        if( bBigEndian ) SwapWord( 4, &nParts );
 
-	ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
-	ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
+        ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
+        ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
 
         nRecordSize = 52;
 
         /*
          * Write part start positions.
          */
-	ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
+        ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
                   4 * psObject->nParts );
-	for( i = 0; i < psObject->nParts; i++ )
-	{
-	    if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
+        for( i = 0; i < psObject->nParts; i++ )
+        {
+            if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
             nRecordSize += 4;
-	}
+        }
 
         /*
          * Write multipatch part types if needed.
@@ -1012,19 +1281,19 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
         /*
          * Write the (x,y) vertex values.
          */
-	for( i = 0; i < psObject->nVertices; i++ )
-	{
-	    ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
-	    ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
+        for( i = 0; i < psObject->nVertices; i++ )
+        {
+            ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
+            ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
 
-	    if( bBigEndian )
+            if( bBigEndian )
                 SwapWord( 8, pabyRec + nRecordSize );
             
-	    if( bBigEndian )
+            if( bBigEndian )
                 SwapWord( 8, pabyRec + nRecordSize + 8 );
 
             nRecordSize += 2 * 8;
-	}
+        }
 
         /*
          * Write the Z coordinates (if any).
@@ -1052,13 +1321,14 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
         /*
          * Write the M values, if any.
          */
-        if( psObject->nSHPType == SHPT_POLYGONM
-            || psObject->nSHPType == SHPT_ARCM
+        if( psObject->bMeasureIsUsed
+            && (psObject->nSHPType == SHPT_POLYGONM
+                || psObject->nSHPType == SHPT_ARCM
 #ifndef DISABLE_MULTIPATCH_MEASURE            
-            || psObject->nSHPType == SHPT_MULTIPATCH
+                || psObject->nSHPType == SHPT_MULTIPATCH
 #endif            
-            || psObject->nSHPType == SHPT_POLYGONZ
-            || psObject->nSHPType == SHPT_ARCZ )
+                || psObject->nSHPType == SHPT_POLYGONZ
+                || psObject->nSHPType == SHPT_ARCZ) )
         {
             ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
@@ -1084,26 +1354,26 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
              || psObject->nSHPType == SHPT_MULTIPOINTZ
              || psObject->nSHPType == SHPT_MULTIPOINTM )
     {
-	int32		nPoints;
-	int    		i;
+        int32		nPoints;
+        int    		i;
 
-	nPoints = psObject->nVertices;
+        nPoints = psObject->nVertices;
 
         _SHPSetBounds( pabyRec + 12, psObject );
 
-	if( bBigEndian ) SwapWord( 4, &nPoints );
-	ByteCopy( &nPoints, pabyRec + 44, 4 );
+        if( bBigEndian ) SwapWord( 4, &nPoints );
+        ByteCopy( &nPoints, pabyRec + 44, 4 );
 	
-	for( i = 0; i < psObject->nVertices; i++ )
-	{
-	    ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
-	    ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
+        for( i = 0; i < psObject->nVertices; i++ )
+        {
+            ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
+            ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
 
-	    if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
-	    if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
-	}
+            if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
+        }
 
-	nRecordSize = 48 + 16 * psObject->nVertices;
+        nRecordSize = 48 + 16 * psObject->nVertices;
 
         if( psObject->nSHPType == SHPT_MULTIPOINTZ )
         {
@@ -1123,8 +1393,9 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
             }
         }
 
-        if( psObject->nSHPType == SHPT_MULTIPOINTZ
-            || psObject->nSHPType == SHPT_MULTIPOINTM )
+        if( psObject->bMeasureIsUsed
+            && (psObject->nSHPType == SHPT_MULTIPOINTZ
+                || psObject->nSHPType == SHPT_MULTIPOINTM) )
         {
             ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
@@ -1150,11 +1421,11 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
              || psObject->nSHPType == SHPT_POINTZ
              || psObject->nSHPType == SHPT_POINTM )
     {
-	ByteCopy( psObject->padfX, pabyRec + 12, 8 );
-	ByteCopy( psObject->padfY, pabyRec + 20, 8 );
+        ByteCopy( psObject->padfX, pabyRec + 12, 8 );
+        ByteCopy( psObject->padfY, pabyRec + 20, 8 );
 
-	if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
-	if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
+        if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
+        if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
 
         nRecordSize = 28;
         
@@ -1165,8 +1436,9 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
             nRecordSize += 8;
         }
         
-        if( psObject->nSHPType == SHPT_POINTZ
-            || psObject->nSHPType == SHPT_POINTM )
+        if( psObject->bMeasureIsUsed
+            && (psObject->nSHPType == SHPT_POINTZ
+                || psObject->nSHPType == SHPT_POINTM) )
         {
             ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
             if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
@@ -1195,6 +1467,18 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
 /* -------------------------------------------------------------------- */
     if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
     {
+        unsigned int nExpectedSize = psSHP->nFileSize + nRecordSize;
+        if( nExpectedSize < psSHP->nFileSize ) // due to unsigned int overflow
+        {
+            char str[128];
+            sprintf( str, "Failed to write shape object. "
+                     "File size cannot reach %u + %u.",
+                     psSHP->nFileSize, nRecordSize );
+            psSHP->sHooks.Error( str );
+            free( pabyRec );
+            return -1;
+        }
+
         if( nShapeId == -1 )
             nShapeId = psSHP->nRecords++;
 
@@ -1205,6 +1489,7 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
     else
     {
         nRecordOffset = psSHP->panRecOffset[nShapeId];
+        psSHP->panRecSize[nShapeId] = nRecordSize-8;
     }
     
 /* -------------------------------------------------------------------- */
@@ -1225,10 +1510,15 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
 /* -------------------------------------------------------------------- */
 /*      Write out record.                                               */
 /* -------------------------------------------------------------------- */
-    if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
-        || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
+    if( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 )
+    {
+        psSHP->sHooks.Error( "Error in psSHP->sHooks.FSeek() while writing object to .shp file." );
+        free( pabyRec );
+        return -1;
+    }
+    if( psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
     {
-        printf( "Error in fseek() or fwrite().\n" );
+        psSHP->sHooks.Error( "Error in psSHP->sHooks.Fwrite() while writing object to .shp file." );
         free( pabyRec );
         return -1;
     }
@@ -1241,25 +1531,34 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
     if( psSHP->adBoundsMin[0] == 0.0
         && psSHP->adBoundsMax[0] == 0.0
         && psSHP->adBoundsMin[1] == 0.0
-        && psSHP->adBoundsMax[1] == 0.0 
-        && psObject->nSHPType != SHPT_NULL )
+        && psSHP->adBoundsMax[1] == 0.0 )
     {
-        psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
-        psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
-        psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
-        psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
+        if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 )
+        {
+            psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
+            psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
+            psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
+            psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
+        }
+        else
+        {
+            psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
+            psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
+            psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
+            psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
+        }
     }
 
     for( i = 0; i < psObject->nVertices; i++ )
     {
-	psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
-	psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
-	psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
-	psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
-	psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
-	psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
-	psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
-	psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
+        psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
+        psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
+        psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
+        psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
+        psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
+        psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
+        psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
+        psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
     }
 
     return( nShapeId  );
@@ -1276,7 +1575,9 @@ SHPObject SHPAPI_CALL1(*)
 SHPReadObject( SHPHandle psSHP, int hEntity )
 
 {
-    SHPObject		*psShape;
+    int                  nEntitySize, nRequiredSize;
+    SHPObject           *psShape;
+    char                 szErrorMsg[128];
 
 /* -------------------------------------------------------------------- */
 /*      Validate the record/entity number.                              */
@@ -1287,25 +1588,85 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
 /* -------------------------------------------------------------------- */
 /*      Ensure our record buffer is large enough.                       */
 /* -------------------------------------------------------------------- */
-    if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
+    nEntitySize = psSHP->panRecSize[hEntity]+8;
+    if( nEntitySize > psSHP->nBufSize )
+    {
+        psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
+        if (psSHP->pabyRec == NULL)
+        {
+            char szError[200];
+
+            /* Reallocate previous successfull size for following features */
+            psSHP->pabyRec = (uchar *) malloc(psSHP->nBufSize);
+
+            sprintf( szError, 
+                     "Not enough memory to allocate requested memory (nBufSize=%d). "
+                     "Probably broken SHP file", psSHP->nBufSize );
+            psSHP->sHooks.Error( szError );
+            return NULL;
+        }
+
+        /* Only set new buffer size after successfull alloc */
+        psSHP->nBufSize = nEntitySize;
+    }
+
+    /* In case we were not able to reallocate the buffer on a previous step */
+    if (psSHP->pabyRec == NULL)
     {
-	psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
-	psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
+        return NULL;
     }
 
 /* -------------------------------------------------------------------- */
 /*      Read the record.                                                */
 /* -------------------------------------------------------------------- */
-    fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 );
-    fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );
+    if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 )
+    {
+        /*
+         * TODO - mloskot: Consider detailed diagnostics of shape file,
+         * for example to detect if file is truncated.
+         */
+        char str[128];
+        sprintf( str,
+                 "Error in fseek() reading object from .shp file at offset %u",
+                 psSHP->panRecOffset[hEntity]);
+
+        psSHP->sHooks.Error( str );
+        return NULL;
+    }
+
+    if( psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1, psSHP->fpSHP ) != 1 )
+    {
+        /*
+         * TODO - mloskot: Consider detailed diagnostics of shape file,
+         * for example to detect if file is truncated.
+         */
+        char str[128];
+        sprintf( str,
+                 "Error in fread() reading object of size %u at offset %u from .shp file",
+                 nEntitySize, psSHP->panRecOffset[hEntity] );
+
+        psSHP->sHooks.Error( str );
+        return NULL;
+    }
 
 /* -------------------------------------------------------------------- */
 /*	Allocate and minimally initialize the object.			*/
 /* -------------------------------------------------------------------- */
     psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
     psShape->nShapeId = hEntity;
+    psShape->bMeasureIsUsed = FALSE;
 
+    if ( 8 + 4 > nEntitySize )
+    {
+        snprintf(szErrorMsg, sizeof(szErrorMsg),
+                 "Corrupted .shp file : shape %d : nEntitySize = %d",
+                 hEntity, nEntitySize); 
+        psSHP->sHooks.Error( szErrorMsg );
+        SHPDestroyObject(psShape);
+        return NULL;
+    }
     memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
+
     if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
 
 /* ==================================================================== */
@@ -1318,9 +1679,18 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
         || psShape->nSHPType == SHPT_ARCM
         || psShape->nSHPType == SHPT_MULTIPATCH )
     {
-	int32		nPoints, nParts;
-	int    		i, nOffset;
+        int32		nPoints, nParts;
+        int    		i, nOffset;
 
+        if ( 40 + 8 + 4 > nEntitySize )
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d : nEntitySize = %d",
+                     hEntity, nEntitySize); 
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 /* -------------------------------------------------------------------- */
 /*	Get the X/Y bounds.						*/
 /* -------------------------------------------------------------------- */
@@ -1329,30 +1699,80 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
         memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
         memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
 
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
 
 /* -------------------------------------------------------------------- */
 /*      Extract part/point count, and build vertex and part arrays      */
 /*      to proper size.                                                 */
 /* -------------------------------------------------------------------- */
-	memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
-	memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
+        memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
+        memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
 
-	if( bBigEndian ) SwapWord( 4, &nPoints );
-	if( bBigEndian ) SwapWord( 4, &nParts );
+        if( bBigEndian ) SwapWord( 4, &nPoints );
+        if( bBigEndian ) SwapWord( 4, &nParts );
+
+        if (nPoints < 0 || nParts < 0 ||
+            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
+                     hEntity, nPoints, nParts);
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+        
+        /* With the previous checks on nPoints and nParts, */
+        /* we should not overflow here and after */
+        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
+        nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
+        if ( psShape->nSHPType == SHPT_POLYGONZ
+             || psShape->nSHPType == SHPT_ARCZ
+             || psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            nRequiredSize += 16 + 8 * nPoints;
+        }
+        if( psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            nRequiredSize += 4 * nParts;
+        }
+        if (nRequiredSize > nEntitySize)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
+                     hEntity, nPoints, nParts, nEntitySize);
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 
-	psShape->nVertices = nPoints;
+        psShape->nVertices = nPoints;
         psShape->padfX = (double *) calloc(nPoints,sizeof(double));
         psShape->padfY = (double *) calloc(nPoints,sizeof(double));
         psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
         psShape->padfM = (double *) calloc(nPoints,sizeof(double));
 
-	psShape->nParts = nParts;
+        psShape->nParts = nParts;
         psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
         psShape->panPartType = (int *) calloc(nParts,sizeof(int));
+        
+        if (psShape->padfX == NULL ||
+            psShape->padfY == NULL ||
+            psShape->padfZ == NULL ||
+            psShape->padfM == NULL ||
+            psShape->panPartStart == NULL ||
+            psShape->panPartType == NULL)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
+                     "Probably broken SHP file", hEntity, nPoints, nParts );
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 
         for( i = 0; i < nParts; i++ )
             psShape->panPartType[i] = SHPP_RING;
@@ -1360,13 +1780,35 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
 /* -------------------------------------------------------------------- */
 /*      Copy out the part array from the record.                        */
 /* -------------------------------------------------------------------- */
-	memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
-	for( i = 0; i < nParts; i++ )
-	{
-	    if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
-	}
+        memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
+        for( i = 0; i < nParts; i++ )
+        {
+            if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
+
+            /* We check that the offset is inside the vertex array */
+            if (psShape->panPartStart[i] < 0
+                || (psShape->panPartStart[i] >= psShape->nVertices
+                    && psShape->nVertices > 0) )
+            {
+                snprintf(szErrorMsg, sizeof(szErrorMsg),
+                         "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
+                         hEntity, i, psShape->panPartStart[i], psShape->nVertices); 
+                psSHP->sHooks.Error( szErrorMsg );
+                SHPDestroyObject(psShape);
+                return NULL;
+            }
+            if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
+            {
+                snprintf(szErrorMsg, sizeof(szErrorMsg),
+                         "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
+                         hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]); 
+                psSHP->sHooks.Error( szErrorMsg );
+                SHPDestroyObject(psShape);
+                return NULL;
+            }
+        }
 
-	nOffset = 44 + 8 + 4*nParts;
+        nOffset = 44 + 8 + 4*nParts;
 
 /* -------------------------------------------------------------------- */
 /*      If this is a multipatch, we will also have parts types.         */
@@ -1385,19 +1827,19 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
 /* -------------------------------------------------------------------- */
 /*      Copy out the vertices from the record.                          */
 /* -------------------------------------------------------------------- */
-	for( i = 0; i < nPoints; i++ )
-	{
-	    memcpy(psShape->padfX + i,
-		   psSHP->pabyRec + nOffset + i * 16,
-		   8 );
+        for( i = 0; i < nPoints; i++ )
+        {
+            memcpy(psShape->padfX + i,
+                   psSHP->pabyRec + nOffset + i * 16,
+                   8 );
 
-	    memcpy(psShape->padfY + i,
-		   psSHP->pabyRec + nOffset + i * 16 + 8,
-		   8 );
+            memcpy(psShape->padfY + i,
+                   psSHP->pabyRec + nOffset + i * 16 + 8,
+                   8 );
 
-	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
-	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
-	}
+            if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+            if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+        }
 
         nOffset += 16*nPoints;
         
@@ -1430,7 +1872,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
 /*      big enough, but really it will only occur for the Z shapes      */
 /*      (options), and the M shapes.                                    */
 /* -------------------------------------------------------------------- */
-        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        if( nEntitySize >= nOffset + 16 + 8*nPoints )
         {
             memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
             memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
@@ -1444,8 +1886,8 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
                         psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                 if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
             }
+            psShape->bMeasureIsUsed = TRUE;
         }
-        
     }
 
 /* ==================================================================== */
@@ -1455,26 +1897,74 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
              || psShape->nSHPType == SHPT_MULTIPOINTM
              || psShape->nSHPType == SHPT_MULTIPOINTZ )
     {
-	int32		nPoints;
-	int    		i, nOffset;
+        int32		nPoints;
+        int    		i, nOffset;
+
+        if ( 44 + 4 > nEntitySize )
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d : nEntitySize = %d",
+                     hEntity, nEntitySize); 
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+        memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
 
-	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
-	if( bBigEndian ) SwapWord( 4, &nPoints );
+        if( bBigEndian ) SwapWord( 4, &nPoints );
+
+        if (nPoints < 0 || nPoints > 50 * 1000 * 1000)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d : nPoints = %d",
+                     hEntity, nPoints); 
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
 
-	psShape->nVertices = nPoints;
+        nRequiredSize = 48 + nPoints * 16;
+        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
+        {
+            nRequiredSize += 16 + nPoints * 8;
+        }
+        if (nRequiredSize > nEntitySize)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
+                     hEntity, nPoints, nEntitySize); 
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+        
+        psShape->nVertices = nPoints;
         psShape->padfX = (double *) calloc(nPoints,sizeof(double));
         psShape->padfY = (double *) calloc(nPoints,sizeof(double));
         psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
         psShape->padfM = (double *) calloc(nPoints,sizeof(double));
 
-	for( i = 0; i < nPoints; i++ )
-	{
-	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
-	    memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
+        if (psShape->padfX == NULL ||
+            psShape->padfY == NULL ||
+            psShape->padfZ == NULL ||
+            psShape->padfM == NULL)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
+                     "Probably broken SHP file", hEntity, nPoints );
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+
+        for( i = 0; i < nPoints; i++ )
+        {
+            memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
+            memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
 
-	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
-	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
-	}
+            if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+            if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+        }
 
         nOffset = 48 + 16*nPoints;
         
@@ -1486,10 +1976,10 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
         memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
         memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
 
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
-	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+        if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
 
 /* -------------------------------------------------------------------- */
 /*      If we have a Z coordinate, collect that now.                    */
@@ -1518,7 +2008,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
 /*      big enough, but really it will only occur for the Z shapes      */
 /*      (options), and the M shapes.                                    */
 /* -------------------------------------------------------------------- */
-        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        if( nEntitySize >= nOffset + 16 + 8*nPoints )
         {
             memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
             memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
@@ -1532,6 +2022,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
                         psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                 if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
             }
+            psShape->bMeasureIsUsed = TRUE;
         }
     }
 
@@ -1544,17 +2035,26 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
     {
         int	nOffset;
         
-	psShape->nVertices = 1;
+        psShape->nVertices = 1;
         psShape->padfX = (double *) calloc(1,sizeof(double));
         psShape->padfY = (double *) calloc(1,sizeof(double));
         psShape->padfZ = (double *) calloc(1,sizeof(double));
         psShape->padfM = (double *) calloc(1,sizeof(double));
 
-	memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
-	memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
+        if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize)
+        {
+            snprintf(szErrorMsg, sizeof(szErrorMsg),
+                     "Corrupted .shp file : shape %d : nEntitySize = %d",
+                     hEntity, nEntitySize); 
+            psSHP->sHooks.Error( szErrorMsg );
+            SHPDestroyObject(psShape);
+            return NULL;
+        }
+        memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
+        memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
 
-	if( bBigEndian ) SwapWord( 8, psShape->padfX );
-	if( bBigEndian ) SwapWord( 8, psShape->padfY );
+        if( bBigEndian ) SwapWord( 8, psShape->padfX );
+        if( bBigEndian ) SwapWord( 8, psShape->padfY );
 
         nOffset = 20 + 8;
         
@@ -1576,11 +2076,12 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
 /*      big enough, but really it will only occur for the Z shapes      */
 /*      (options), and the M shapes.                                    */
 /* -------------------------------------------------------------------- */
-        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
+        if( nEntitySize >= nOffset + 8 )
         {
             memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
         
             if( bBigEndian ) SwapWord( 8, psShape->padfM );
+            psShape->bMeasureIsUsed = TRUE;
         }
 
 /* -------------------------------------------------------------------- */
@@ -1735,6 +2236,9 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
         && psObject->nSHPType != SHPT_POLYGONM )
         return 0;
 
+    if( psObject->nVertices == 0 || psObject->nParts == 0 )
+        return 0;
+
 /* -------------------------------------------------------------------- */
 /*      Process each of the rings.                                      */
 /* -------------------------------------------------------------------- */
@@ -1749,9 +2253,16 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
 /*      first ring is outer and all others are inner, but eventually    */
 /*      we need to fix this to handle multiple island polygons and      */
 /*      unordered sets of rings.                                        */
+/*                                                                      */
 /* -------------------------------------------------------------------- */
-        dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
-        dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
+
+        /* Use point in the middle of segment to avoid testing
+         * common points of rings.
+         */
+        dfTestX = ( psObject->padfX[psObject->panPartStart[iOpRing]]
+                    + psObject->padfX[psObject->panPartStart[iOpRing] + 1] ) / 2;
+        dfTestY = ( psObject->padfY[psObject->panPartStart[iOpRing]]
+                    + psObject->padfY[psObject->panPartStart[iOpRing] + 1] ) / 2;
 
         bInner = FALSE;
         for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
@@ -1779,21 +2290,31 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
                 else
                     iNext = 0;
 
-                if( (psObject->padfY[iEdge+nVertStart] < dfTestY 
-                     && psObject->padfY[iNext+nVertStart] >= dfTestY)
-                    || (psObject->padfY[iNext+nVertStart] < dfTestY 
-                        && psObject->padfY[iEdge+nVertStart] >= dfTestY) )
+                /* Rule #1:
+                 * Test whether the edge 'straddles' the horizontal ray from the test point (dfTestY,dfTestY)
+                 * The rule #1 also excludes edges collinear with the ray.
+                 */
+                if ( ( psObject->padfY[iEdge+nVertStart] < dfTestY
+                       && dfTestY <= psObject->padfY[iNext+nVertStart] )
+                     || ( psObject->padfY[iNext+nVertStart] < dfTestY
+                          && dfTestY <= psObject->padfY[iEdge+nVertStart] ) )
                 {
-                    if( psObject->padfX[iEdge+nVertStart] 
-                        + (dfTestY - psObject->padfY[iEdge+nVertStart])
-                           / (psObject->padfY[iNext+nVertStart]
-                              - psObject->padfY[iEdge+nVertStart])
-                           * (psObject->padfX[iNext+nVertStart]
-                              - psObject->padfX[iEdge+nVertStart]) < dfTestX )
+                    /* Rule #2:
+                     * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
+                     */
+                    double const intersect = 
+                        ( psObject->padfX[iEdge+nVertStart]
+                          + ( dfTestY - psObject->padfY[iEdge+nVertStart] ) 
+                          / ( psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart] )
+                          * ( psObject->padfX[iNext+nVertStart] - psObject->padfX[iEdge+nVertStart] ) );
+
+                    if (intersect  < dfTestX)
+                    {
                         bInner = !bInner;
-                }
+                    }
+                }    
             }
-        }
+        } /* for iCheckRing */
 
 /* -------------------------------------------------------------------- */
 /*      Determine the current order of this ring so we will know if     */
@@ -1807,15 +2328,16 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
             nVertCount = psObject->panPartStart[iOpRing+1] 
                 - psObject->panPartStart[iOpRing];
 
-        dfSum = 0.0;
-        for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
+        if (nVertCount < 2)
+            continue;
+
+        dfSum = psObject->padfX[nVertStart] * (psObject->padfY[nVertStart+1] - psObject->padfY[nVertStart+nVertCount-1]);
+        for( iVert = nVertStart + 1; iVert < nVertStart+nVertCount-1; iVert++ )
         {
-            dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1]
-                - psObject->padfY[iVert] * psObject->padfX[iVert+1];
+            dfSum += psObject->padfX[iVert] * (psObject->padfY[iVert+1] - psObject->padfY[iVert-1]);
         }
 
-        dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
-               - psObject->padfY[iVert] * psObject->padfX[nVertStart];
+        dfSum += psObject->padfX[iVert] * (psObject->padfY[nVertStart] - psObject->padfY[iVert-1]);
 
 /* -------------------------------------------------------------------- */
 /*      Reverse if necessary.                                           */
diff --git a/shprewind b/shprewind
deleted file mode 100755
index c1f6f8c..0000000
Binary files a/shprewind and /dev/null differ
diff --git a/shprewind.c b/shprewind.c
index 503ee51..0b2f66d 100644
--- a/shprewind.c
+++ b/shprewind.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shprewind.c,v 1.2 2002/04/10 17:23:11 warmerda Exp $
+ * $Id: shprewind.c,v 1.4 2004-09-26 20:09:35 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Utility to validate and reset the winding order of rings in
@@ -35,6 +35,12 @@
  ******************************************************************************
  *
  * $Log: shprewind.c,v $
+ * Revision 1.4  2004-09-26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
+ * Revision 1.3  2004/01/09 16:39:49  fwarmerdam
+ * include standard include files
+ *
  * Revision 1.2  2002/04/10 17:23:11  warmerda
  * copy from source to destination now
  *
@@ -43,6 +49,8 @@
  *
  */
 
+#include <string.h>
+#include <stdlib.h>
 #include "shapefil.h"
 
 int main( int argc, char ** argv )
@@ -90,7 +98,6 @@ int main( int argc, char ** argv )
 /* -------------------------------------------------------------------- */
     for( i = 0; i < nEntities; i++ )
     {
-	int		j;
         SHPObject	*psShape;
 
 	psShape = SHPReadObject( hSHP, i );
diff --git a/shptest.c b/shptest.c
index 83b471a..4336eea 100644
--- a/shptest.c
+++ b/shptest.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shptest.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $
+ * $Id: shptest.c,v 1.7 2004-09-26 20:09:35 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Application for generating sample Shapefiles of various types.
@@ -35,6 +35,9 @@
  ******************************************************************************
  *
  * $Log: shptest.c,v $
+ * Revision 1.7  2004-09-26 20:09:35  fwarmerdam
+ * avoid rcsid warnings
+ *
  * Revision 1.6  2002/01/15 14:36:07  warmerda
  * updated email address
  *
@@ -55,13 +58,12 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shptest.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $";
-
 #include <stdlib.h>
 #include <string.h>
 #include "shapefil.h"
 
+SHP_CVSID("$Id: shptest.c,v 1.7 2004-09-26 20:09:35 fwarmerdam Exp $")
+
 /************************************************************************/
 /*                          Test_WritePoints()                          */
 /*                                                                      */
diff --git a/shptree.c b/shptree.c
index 98d5ce0..409134e 100644
--- a/shptree.c
+++ b/shptree.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shptree.c,v 1.9 2003/01/28 15:53:41 warmerda Exp $
+ * $Id: shptree.c,v 1.17 2012-01-27 21:09:26 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Implementation of quadtree building and searching functions.
@@ -34,6 +34,30 @@
  ******************************************************************************
  *
  * $Log: shptree.c,v $
+ * Revision 1.17  2012-01-27 21:09:26  fwarmerdam
+ * optimize .qix output (gdal #4472)
+ *
+ * Revision 1.16  2011-12-11 22:26:46  fwarmerdam
+ * upgrade .qix access code to use SAHooks (gdal #3365)
+ *
+ * Revision 1.15  2011-07-24 05:59:25  fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
+ *
+ * Revision 1.14  2010-08-27 23:43:27  fwarmerdam
+ * add SHPAPI_CALL attribute in code
+ *
+ * Revision 1.13  2010-06-29 05:50:15  fwarmerdam
+ * fix sign of Z/M comparisons in SHPCheckObjectContained (#2223)
+ *
+ * Revision 1.12  2008-11-12 15:39:50  fwarmerdam
+ * improve safety in face of buggy .shp file.
+ *
+ * Revision 1.11  2007/10/27 03:31:14  fwarmerdam
+ * limit default depth of tree to 12 levels (gdal ticket #1594)
+ *
+ * Revision 1.10  2005/01/03 22:30:13  fwarmerdam
+ * added support for saved quadtrees
+ *
  * Revision 1.9  2003/01/28 15:53:41  warmerda
  * Avoid build warnings.
  *
@@ -63,9 +87,6 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shptree.c,v 1.9 2003/01/28 15:53:41 warmerda Exp $";
-
 #include "shapefil.h"
 
 #include <math.h>
@@ -73,11 +94,19 @@ static char rcsid[] =
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef USE_CPL
+#include "cpl_error.h"
+#endif
+
+SHP_CVSID("$Id: shptree.c,v 1.17 2012-01-27 21:09:26 fwarmerdam Exp $")
+
 #ifndef TRUE
 #  define TRUE 1
 #  define FALSE 0
 #endif
 
+static int bBigEndian = 0;
+
 
 /* -------------------------------------------------------------------- */
 /*      If the following is 0.5, nodes will be split in half.  If it    */
@@ -118,6 +147,8 @@ static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin,
     SHPTreeNode	*psTreeNode;
 
     psTreeNode = (SHPTreeNode *) malloc(sizeof(SHPTreeNode));
+    if( NULL == psTreeNode )
+        return NULL;
 
     psTreeNode->nShapeCount = 0;
     psTreeNode->panShapeIds = NULL;
@@ -140,8 +171,8 @@ static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin,
 /************************************************************************/
 
 SHPTree SHPAPI_CALL1(*)
-SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
-               double *padfBoundsMin, double *padfBoundsMax )
+    SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
+                   double *padfBoundsMin, double *padfBoundsMax )
 
 {
     SHPTree	*psTree;
@@ -153,10 +184,15 @@ SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
 /*      Allocate the tree object                                        */
 /* -------------------------------------------------------------------- */
     psTree = (SHPTree *) malloc(sizeof(SHPTree));
+    if( NULL == psTree )
+    {
+        return NULL;
+    }
 
     psTree->hSHP = hSHP;
     psTree->nMaxDepth = nMaxDepth;
     psTree->nDimension = nDimension;
+    psTree->nTotalCount = 0;
 
 /* -------------------------------------------------------------------- */
 /*      If no max depth was defined, try to select a reasonable one     */
@@ -173,18 +209,46 @@ SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
             psTree->nMaxDepth += 1;
             nMaxNodeCount = nMaxNodeCount * 2;
         }
+
+#ifdef USE_CPL
+        CPLDebug( "Shape",
+                  "Estimated spatial index tree depth: %d",
+                  psTree->nMaxDepth );
+#endif
+
+        /* NOTE: Due to problems with memory allocation for deep trees,
+         * automatically estimated depth is limited up to 12 levels.
+         * See Ticket #1594 for detailed discussion.
+         */
+        if( psTree->nMaxDepth > MAX_DEFAULT_TREE_DEPTH )
+        {
+            psTree->nMaxDepth = MAX_DEFAULT_TREE_DEPTH;
+
+#ifdef USE_CPL
+            CPLDebug( "Shape",
+                      "Falling back to max number of allowed index tree levels (%d).",
+                      MAX_DEFAULT_TREE_DEPTH );
+#endif
+        }
     }
 
 /* -------------------------------------------------------------------- */
 /*      Allocate the root node.                                         */
 /* -------------------------------------------------------------------- */
     psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax );
+    if( NULL == psTree->psRoot )
+    {
+        return NULL;
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Assign the bounds to the root node.  If none are passed in,     */
 /*      use the bounds of the provided file otherwise the create        */
 /*      function will have already set the bounds.                      */
 /* -------------------------------------------------------------------- */
+    assert( NULL != psTree );
+    assert( NULL != psTree->psRoot );
+	
     if( padfBoundsMin == NULL )
     {
         SHPGetInfo( hSHP, NULL, NULL,
@@ -206,8 +270,11 @@ SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
             SHPObject	*psShape;
             
             psShape = SHPReadObject( hSHP, iShape );
-            SHPTreeAddShapeId( psTree, psShape );
-            SHPDestroyObject( psShape );
+            if( psShape != NULL )
+            {
+                SHPTreeAddShapeId( psTree, psShape );
+                SHPDestroyObject( psShape );
+            }
         }
     }        
 
@@ -223,6 +290,8 @@ static void SHPDestroyTreeNode( SHPTreeNode * psTreeNode )
 {
     int		i;
     
+	assert( NULL != psTreeNode );
+
     for( i = 0; i < psTreeNode->nSubNodes; i++ )
     {
         if( psTreeNode->apsSubNode[i] != NULL )
@@ -306,14 +375,14 @@ static int SHPCheckObjectContained( SHPObject * psObject, int nDimension,
         return TRUE;
     
     if( psObject->dfZMin < padfBoundsMin[2]
-        || psObject->dfZMax < padfBoundsMax[2] )
+        || psObject->dfZMax > padfBoundsMax[2] )
         return FALSE;
         
     if( nDimension == 3 )
         return TRUE;
 
     if( psObject->dfMMin < padfBoundsMin[3]
-        || psObject->dfMMax < padfBoundsMax[3] )
+        || psObject->dfMMax > padfBoundsMax[3] )
         return FALSE;
 
     return TRUE;
@@ -494,14 +563,14 @@ SHPTreeNodeAddShapeId( SHPTreeNode * psTreeNode, SHPObject * psObject,
 /* -------------------------------------------------------------------- */
     psTreeNode->nShapeCount++;
 
-    psTreeNode->panShapeIds =
+    psTreeNode->panShapeIds = (int *) 
         SfRealloc( psTreeNode->panShapeIds,
                    sizeof(int) * psTreeNode->nShapeCount );
     psTreeNode->panShapeIds[psTreeNode->nShapeCount-1] = psObject->nShapeId;
 
     if( psTreeNode->papsShapeObj != NULL )
     {
-        psTreeNode->papsShapeObj =
+        psTreeNode->papsShapeObj = (SHPObject **)
             SfRealloc( psTreeNode->papsShapeObj,
                        sizeof(void *) * psTreeNode->nShapeCount );
         psTreeNode->papsShapeObj[psTreeNode->nShapeCount-1] = NULL;
@@ -521,6 +590,8 @@ int SHPAPI_CALL
 SHPTreeAddShapeId( SHPTree * psTree, SHPObject * psObject )
 
 {
+    psTree->nTotalCount++;
+
     return( SHPTreeNodeAddShapeId( psTree->psRoot, psObject,
                                    psTree->nMaxDepth, psTree->nDimension ) );
 }
@@ -658,6 +729,29 @@ static int SHPTreeNodeTrim( SHPTreeNode * psTreeNode )
     }
 
 /* -------------------------------------------------------------------- */
+/*      If the current node has 1 subnode and no shapes, promote that   */
+/*      subnode to the current node position.                           */
+/* -------------------------------------------------------------------- */
+    if( psTreeNode->nSubNodes == 1 && psTreeNode->nShapeCount == 0)
+    {
+        SHPTreeNode* psSubNode = psTreeNode->apsSubNode[0];
+
+        memcpy(psTreeNode->adfBoundsMin, psSubNode->adfBoundsMin,
+               sizeof(psSubNode->adfBoundsMin));
+        memcpy(psTreeNode->adfBoundsMax, psSubNode->adfBoundsMax,
+               sizeof(psSubNode->adfBoundsMax));
+        psTreeNode->nShapeCount = psSubNode->nShapeCount;
+        assert(psTreeNode->panShapeIds == NULL);
+        psTreeNode->panShapeIds = psSubNode->panShapeIds;
+        assert(psTreeNode->papsShapeObj == NULL);
+        psTreeNode->papsShapeObj = psSubNode->papsShapeObj;
+        psTreeNode->nSubNodes = psSubNode->nSubNodes;
+        for( i = 0; i < psSubNode->nSubNodes; i++ )
+            psTreeNode->apsSubNode[i] = psSubNode->apsSubNode[i];
+        free(psSubNode);
+    }
+
+/* -------------------------------------------------------------------- */
 /*      We should be trimmed if we have no subnodes, and no shapes.     */
 /* -------------------------------------------------------------------- */
     return( psTreeNode->nSubNodes == 0 && psTreeNode->nShapeCount == 0 );
@@ -677,3 +771,417 @@ SHPTreeTrimExtraNodes( SHPTree * hTree )
     SHPTreeNodeTrim( hTree->psRoot );
 }
 
+/************************************************************************/
+/*                              SwapWord()                              */
+/*                                                                      */
+/*      Swap a 2, 4 or 8 byte word.                                     */
+/************************************************************************/
+
+static void SwapWord( int length, void * wordP )
+
+{
+    int		i;
+    unsigned char	temp;
+
+    for( i=0; i < length/2; i++ )
+    {
+	temp = ((unsigned char *) wordP)[i];
+	((unsigned char *)wordP)[i] = ((unsigned char *) wordP)[length-i-1];
+	((unsigned char *) wordP)[length-i-1] = temp;
+    }
+}
+
+
+struct SHPDiskTreeInfo
+{
+    SAHooks sHooks;
+    SAFile  fpQIX;
+};
+
+/************************************************************************/
+/*                         SHPOpenDiskTree()                            */
+/************************************************************************/
+
+SHPTreeDiskHandle SHPOpenDiskTree( const char* pszQIXFilename,
+                                   SAHooks *psHooks )
+{
+    SHPTreeDiskHandle hDiskTree;
+
+    hDiskTree = (SHPTreeDiskHandle) calloc(sizeof(struct SHPDiskTreeInfo),1);
+
+    if (psHooks == NULL)
+        SASetupDefaultHooks( &(hDiskTree->sHooks) );
+    else
+        memcpy( &(hDiskTree->sHooks), psHooks, sizeof(SAHooks) );
+
+    hDiskTree->fpQIX = hDiskTree->sHooks.FOpen(pszQIXFilename, "rb");
+    if (hDiskTree->fpQIX == NULL)
+    {
+        free(hDiskTree);
+        return NULL;
+    }
+
+    return hDiskTree;
+}
+
+/***********************************************************************/
+/*                         SHPCloseDiskTree()                           */
+/************************************************************************/
+
+void SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree )
+{
+    if (hDiskTree == NULL)
+        return;
+
+    hDiskTree->sHooks.FClose(hDiskTree->fpQIX);
+    free(hDiskTree);
+}
+
+/************************************************************************/
+/*                       SHPSearchDiskTreeNode()                        */
+/************************************************************************/
+
+static int
+SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, double *padfBoundsMax,
+                       int **ppanResultBuffer, int *pnBufferMax, 
+                       int *pnResultCount, int bNeedSwap )
+
+{
+    int i;
+    int offset;
+    int numshapes, numsubnodes;
+    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];
+
+/* -------------------------------------------------------------------- */
+/*      Read and unswap first part of node info.                        */
+/* -------------------------------------------------------------------- */
+    hDiskTree->sHooks.FRead( &offset, 4, 1, hDiskTree->fpQIX );
+    if ( bNeedSwap ) SwapWord ( 4, &offset );
+
+    hDiskTree->sHooks.FRead( adfNodeBoundsMin, sizeof(double), 2, hDiskTree->fpQIX );
+    hDiskTree->sHooks.FRead( adfNodeBoundsMax, sizeof(double), 2, hDiskTree->fpQIX );
+    if ( bNeedSwap )
+    {
+        SwapWord( 8, adfNodeBoundsMin + 0 );
+        SwapWord( 8, adfNodeBoundsMin + 1 );
+        SwapWord( 8, adfNodeBoundsMax + 0 );
+        SwapWord( 8, adfNodeBoundsMax + 1 );
+    }
+      
+    hDiskTree->sHooks.FRead( &numshapes, 4, 1, hDiskTree->fpQIX );
+    if ( bNeedSwap ) SwapWord ( 4, &numshapes );
+
+/* -------------------------------------------------------------------- */
+/*      If we don't overlap this node at all, we can just fseek()       */
+/*      pass this node info and all subnodes.                           */
+/* -------------------------------------------------------------------- */
+    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
+                                padfBoundsMin, padfBoundsMax, 2 ) )
+    {
+        offset += numshapes*sizeof(int) + sizeof(int);
+        hDiskTree->sHooks.FSeek(hDiskTree->fpQIX, offset, SEEK_CUR);
+        return TRUE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Add all the shapeids at this node to our list.                  */
+/* -------------------------------------------------------------------- */
+    if(numshapes > 0) 
+    {
+        if( *pnResultCount + numshapes > *pnBufferMax )
+        {
+            *pnBufferMax = (int) ((*pnResultCount + numshapes + 100) * 1.25);
+            *ppanResultBuffer = (int *) 
+                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );
+        }
+
+        hDiskTree->sHooks.FRead( *ppanResultBuffer + *pnResultCount, 
+               sizeof(int), numshapes, hDiskTree->fpQIX );
+
+        if (bNeedSwap )
+        {
+            for( i=0; i<numshapes; i++ )
+                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
+        }
+
+        *pnResultCount += numshapes; 
+    } 
+
+/* -------------------------------------------------------------------- */
+/*      Process the subnodes.                                           */
+/* -------------------------------------------------------------------- */
+    hDiskTree->sHooks.FRead( &numsubnodes, 4, 1, hDiskTree->fpQIX );
+    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );
+
+    for(i=0; i<numsubnodes; i++)
+    {
+        if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, 
+                                    ppanResultBuffer, pnBufferMax, 
+                                    pnResultCount, bNeedSwap ) )
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                          SHPTreeReadLibc()                           */
+/************************************************************************/
+
+static
+SAOffset SHPTreeReadLibc( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+    return (SAOffset) fread( p, (size_t) size, (size_t) nmemb,
+                                 (FILE *) file );
+}
+
+/************************************************************************/
+/*                          SHPTreeSeekLibc()                           */
+/************************************************************************/
+
+static
+SAOffset SHPTreeSeekLibc( SAFile file, SAOffset offset, int whence )
+
+{
+    return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
+}
+
+/************************************************************************/
+/*                         SHPSearchDiskTree()                          */
+/************************************************************************/
+
+int SHPAPI_CALL1(*) 
+SHPSearchDiskTree( FILE *fp, 
+                   double *padfBoundsMin, double *padfBoundsMax,
+                   int *pnShapeCount )
+{
+    struct SHPDiskTreeInfo sDiskTree;
+    memset(&sDiskTree.sHooks, 0, sizeof(sDiskTree.sHooks));
+
+    /* We do not use SASetupDefaultHooks() because the FILE* */
+    /* is a libc FILE* */
+    sDiskTree.sHooks.FSeek = SHPTreeSeekLibc;
+    sDiskTree.sHooks.FRead = SHPTreeReadLibc;
+
+    sDiskTree.fpQIX = (SAFile)fp;
+
+    return SHPSearchDiskTreeEx( &sDiskTree, padfBoundsMin, padfBoundsMax,
+                                 pnShapeCount );
+}
+
+/***********************************************************************/
+/*                       SHPSearchDiskTreeEx()                         */
+/************************************************************************/
+
+int* SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree, 
+                     double *padfBoundsMin, double *padfBoundsMax,
+                     int *pnShapeCount )
+
+{
+    int i, bNeedSwap, nBufferMax = 0;
+    unsigned char abyBuf[16];
+    int *panResultBuffer = NULL;
+
+    *pnShapeCount = 0;
+
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.	  	        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((unsigned char *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Read the header.                                                */
+/* -------------------------------------------------------------------- */
+    hDiskTree->sHooks.FSeek( hDiskTree->fpQIX, 0, SEEK_SET );
+    hDiskTree->sHooks.FRead( abyBuf, 16, 1, hDiskTree->fpQIX );
+
+    if( memcmp( abyBuf, "SQT", 3 ) != 0 )
+        return NULL;
+
+    if( (abyBuf[3] == 2 && bBigEndian)
+        || (abyBuf[3] == 1 && !bBigEndian) )
+        bNeedSwap = FALSE;
+    else
+        bNeedSwap = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Search through root node and it's decendents.                   */
+/* -------------------------------------------------------------------- */
+    if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, 
+                                &panResultBuffer, &nBufferMax, 
+                                pnShapeCount, bNeedSwap ) )
+    {
+        if( panResultBuffer != NULL )
+            free( panResultBuffer );
+        *pnShapeCount = 0;
+        return NULL;
+    }
+/* -------------------------------------------------------------------- */
+/*      Sort the id array                                               */
+/* -------------------------------------------------------------------- */
+    qsort(panResultBuffer, *pnShapeCount, sizeof(int), compare_ints);
+    
+    return panResultBuffer;
+}
+
+/************************************************************************/
+/*                        SHPGetSubNodeOffset()                         */
+/*                                                                      */
+/*      Determine how big all the subnodes of this node (and their      */
+/*      children) will be.  This will allow disk based searchers to     */
+/*      seek past them all efficiently.                                 */
+/************************************************************************/
+
+static int SHPGetSubNodeOffset( SHPTreeNode *node) 
+{
+    int i;
+    long offset=0;
+
+    for(i=0; i<node->nSubNodes; i++ ) 
+    {
+        if(node->apsSubNode[i]) 
+        {
+            offset += 4*sizeof(double) 
+                + (node->apsSubNode[i]->nShapeCount+3)*sizeof(int);
+            offset += SHPGetSubNodeOffset(node->apsSubNode[i]);
+        }
+    }
+
+    return(offset);
+}
+
+/************************************************************************/
+/*                          SHPWriteTreeNode()                          */
+/************************************************************************/
+
+static void SHPWriteTreeNode( SAFile fp, SHPTreeNode *node, SAHooks* psHooks) 
+{
+    int i,j;
+    int offset;
+    unsigned char *pabyRec = NULL;
+    assert( NULL != node );
+
+    offset = SHPGetSubNodeOffset(node);
+  
+    pabyRec = (unsigned char *) 
+        malloc(sizeof(double) * 4
+               + (3 * sizeof(int)) + (node->nShapeCount * sizeof(int)) );
+    if( NULL == pabyRec )
+    {
+#ifdef USE_CPL
+        CPLError( CE_Fatal, CPLE_OutOfMemory, "Memory allocation failure");
+#endif
+        assert( 0 );
+        return;
+    }
+
+    memcpy( pabyRec, &offset, 4);
+
+    /* minx, miny, maxx, maxy */
+    memcpy( pabyRec+ 4, node->adfBoundsMin+0, sizeof(double) );
+    memcpy( pabyRec+12, node->adfBoundsMin+1, sizeof(double) );
+    memcpy( pabyRec+20, node->adfBoundsMax+0, sizeof(double) );
+    memcpy( pabyRec+28, node->adfBoundsMax+1, sizeof(double) );
+
+    memcpy( pabyRec+36, &node->nShapeCount, 4);
+    j = node->nShapeCount * sizeof(int);
+    memcpy( pabyRec+40, node->panShapeIds, j);
+    memcpy( pabyRec+j+40, &node->nSubNodes, 4);
+
+    psHooks->FWrite( pabyRec, 44+j, 1, fp );
+    free (pabyRec);
+  
+    for(i=0; i<node->nSubNodes; i++ ) 
+    {
+        if(node->apsSubNode[i])
+            SHPWriteTreeNode( fp, node->apsSubNode[i], psHooks);
+    }
+}
+
+/************************************************************************/
+/*                            SHPWriteTree()                            */
+/************************************************************************/
+
+int SHPAPI_CALL SHPWriteTree(SHPTree *tree, const char *filename )
+{
+    SAHooks sHooks;
+
+    SASetupDefaultHooks( &sHooks );
+
+    return SHPWriteTreeLL(tree, filename, &sHooks);
+}
+
+/************************************************************************/
+/*                           SHPWriteTreeLL()                           */
+/************************************************************************/
+
+int SHPWriteTreeLL(SHPTree *tree, const char *filename, SAHooks* psHooks )
+{
+    char		signature[4] = "SQT";
+    int		        i;
+    char		abyBuf[32];
+    SAFile              fp;
+
+    SAHooks sHooks;
+    if (psHooks == NULL)
+    {
+        SASetupDefaultHooks( &sHooks );
+        psHooks = &sHooks;
+    }
+  
+/* -------------------------------------------------------------------- */
+/*      Open the output file.                                           */
+/* -------------------------------------------------------------------- */
+    fp = psHooks->FOpen(filename, "wb");
+    if( fp == NULL ) 
+    {
+        return FALSE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.	  	        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((unsigned char *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+  
+/* -------------------------------------------------------------------- */
+/*      Write the header.                                               */
+/* -------------------------------------------------------------------- */
+    memcpy( abyBuf+0, signature, 3 );
+    
+    if( bBigEndian )
+        abyBuf[3] = 2; /* New MSB */
+    else
+        abyBuf[3] = 1; /* New LSB */
+
+    abyBuf[4] = 1; /* version */
+    abyBuf[5] = 0; /* next 3 reserved */
+    abyBuf[6] = 0;
+    abyBuf[7] = 0;
+
+    psHooks->FWrite( abyBuf, 8, 1, fp );
+
+    psHooks->FWrite( &(tree->nTotalCount), 4, 1, fp );
+
+    /* write maxdepth */
+
+    psHooks->FWrite( &(tree->nMaxDepth), 4, 1, fp );
+
+/* -------------------------------------------------------------------- */
+/*      Write all the nodes "in order".                                 */
+/* -------------------------------------------------------------------- */
+
+    SHPWriteTreeNode( fp, tree->psRoot, psHooks );  
+    
+    psHooks->FClose( fp );
+
+    return TRUE;
+}
diff --git a/shptreedump.c b/shptreedump.c
index caa3c7d..d5c1e3f 100644
--- a/shptreedump.c
+++ b/shptreedump.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shptreedump.c,v 1.7 2002/04/10 16:59:12 warmerda Exp $
+ * $Id: shptreedump.c,v 1.8 2005-01-03 22:30:13 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  Mainline for creating and dumping an ASCII representation of
@@ -35,6 +35,9 @@
  ******************************************************************************
  *
  * $Log: shptreedump.c,v $
+ * Revision 1.8  2005-01-03 22:30:13  fwarmerdam
+ * added support for saved quadtrees
+ *
  * Revision 1.7  2002/04/10 16:59:12  warmerda
  * fixed email
  *
@@ -58,14 +61,14 @@
  *
  */
 
-static char rcsid[] = 
-  "$Id: shptreedump.c,v 1.7 2002/04/10 16:59:12 warmerda Exp $";
-
 #include "shapefil.h"
 
 #include <assert.h>
 #include <stdlib.h>
 #include <math.h>
+#include <string.h>
+
+SHP_CVSID("$Id: shptreedump.c,v 1.8 2005-01-03 22:30:13 fwarmerdam Exp $")
 
 static void SHPTreeNodeDump( SHPTree *, SHPTreeNode *, const char *, int );
 static void SHPTreeNodeSearchAndDump( SHPTree *, double *, double * );
@@ -78,7 +81,8 @@ static void Usage()
 
 {
     printf( "shptreedump [-maxdepth n] [-search xmin ymin xmax ymax]\n"
-            "            [-v] shp_file\n" );
+            "            [-v] [-o indexfilename] [-i indexfilename]\n"
+            "            shp_file\n" );
     exit( 1 );
 }
 
@@ -94,9 +98,11 @@ int main( int argc, char ** argv )
     SHPTree	*psTree;
     int		nExpandShapes = 0;
     int		nMaxDepth = 0;
-    int		nDoSearch = 0;
+    int		bDoSearch = 0;
     double	adfSearchMin[4], adfSearchMax[4];
-    
+    const char *pszOutputIndexFilename = NULL;
+    const char *pszInputIndexFilename = NULL;
+    const char *pszTargetFile = NULL;
 
 /* -------------------------------------------------------------------- */
 /*	Consume flags.							*/
@@ -115,9 +121,21 @@ int main( int argc, char ** argv )
             argv += 2;
             argc -= 2;
         }
+        else if( strcmp(argv[1],"-o") == 0 && argc > 2 )
+        {
+            pszOutputIndexFilename = argv[2];
+            argv += 2;
+            argc -= 2;
+        }
+        else if( strcmp(argv[1],"-i") == 0 && argc > 2 )
+        {
+            pszInputIndexFilename = argv[2];
+            argv += 2;
+            argc -= 2;
+        }
         else if( strcmp(argv[1],"-search") == 0 && argc > 5 )
         {
-            nDoSearch = 1;
+            bDoSearch = 1;
 
             adfSearchMin[0] = atof(argv[2]);
             adfSearchMin[1] = atof(argv[3]);
@@ -137,14 +155,51 @@ int main( int argc, char ** argv )
             argv += 5;
             argc -= 5;
         }
+        else if( pszTargetFile == NULL )				
+        {
+            pszTargetFile = argv[1];
+            argv++;
+            argc--;
+        }
         else
-            break;
+        {
+            printf( "Unrecognised argument: %s\n", argv[1] );
+            Usage();
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Do a search with an existing index file?                        */
+/* -------------------------------------------------------------------- */
+    if( bDoSearch && pszInputIndexFilename != NULL )
+    {
+        FILE *fp = fopen( pszInputIndexFilename, "rb" );
+        int  *panResult, nResultCount = 0, iResult;
+
+        if( fp == NULL )
+        {
+            perror( pszInputIndexFilename );
+            exit( 1 );
+        }
+
+        panResult = SHPSearchDiskTree( fp, adfSearchMin, adfSearchMax, 
+                                       &nResultCount );
+
+        printf( "Result: " );
+        for( iResult = 0; iResult < nResultCount; iResult++ )
+            printf( "%d ", panResult[iResult] );
+        printf( "\n" );
+        free( panResult );
+
+        fclose( fp );
+        
+        exit( 0 );
     }
 
 /* -------------------------------------------------------------------- */
 /*      Display a usage message.                                        */
 /* -------------------------------------------------------------------- */
-    if( argc < 2 )
+    if( pszTargetFile == NULL )
     {
         Usage();
     }
@@ -152,11 +207,11 @@ int main( int argc, char ** argv )
 /* -------------------------------------------------------------------- */
 /*      Open the passed shapefile.                                      */
 /* -------------------------------------------------------------------- */
-    hSHP = SHPOpen( argv[1], "rb" );
+    hSHP = SHPOpen( pszTargetFile, "rb" );
 
     if( hSHP == NULL )
     {
-	printf( "Unable to open:%s\n", argv[1] );
+	printf( "Unable to open:%s\n", pszTargetFile );
 	exit( 1 );
     }
 
@@ -169,11 +224,19 @@ int main( int argc, char ** argv )
 /*      Trim unused nodes from the tree.                                */
 /* -------------------------------------------------------------------- */
     SHPTreeTrimExtraNodes( psTree );
-        
+
+/* -------------------------------------------------------------------- */
+/*      Dump tree to .qix file.                                         */
+/* -------------------------------------------------------------------- */
+    if( pszOutputIndexFilename != NULL )
+    {
+        SHPWriteTree( psTree, pszOutputIndexFilename );
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Dump tree by recursive descent.                                 */
 /* -------------------------------------------------------------------- */
-    if( !nDoSearch )
+    else if( !bDoSearch )
         SHPTreeNodeDump( psTree, psTree->psRoot, "", nExpandShapes );
 
 /* -------------------------------------------------------------------- */
diff --git a/shputils.c b/shputils.c
index 2a04f5e..b2c7f06 100644
--- a/shputils.c
+++ b/shputils.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shputils.c,v 1.7 2003/02/25 17:20:22 warmerda Exp $
+ * $Id: shputils.c,v 1.10 2007-12-13 19:59:23 fwarmerdam Exp $
  *
  * Project:  Shapelib
  * Purpose:  
@@ -53,6 +53,15 @@
  ******************************************************************************
  *
  * $Log: shputils.c,v $
+ * Revision 1.10  2007-12-13 19:59:23  fwarmerdam
+ * reindent code, avoid some warnings.
+ *
+ * Revision 1.9  2004/01/14 14:56:00  fwarmerdam
+ * Some cleanlyness improvements.
+ *
+ * Revision 1.8  2004/01/14 14:40:22  fwarmerdam
+ * Fixed exit() call to include code.
+ *
  * Revision 1.7  2003/02/25 17:20:22  warmerda
  * Set psCShape to NULL after SHPDestroyObject() to avoid multi-frees of
  * the same memory ... as submitted by Fred Fox.
@@ -76,11 +85,12 @@
  * Initial revision
  */
 
-static char rcsid[] = 
-  "$Id: shputils.c,v 1.7 2003/02/25 17:20:22 warmerda Exp $";
-
 #include "shapefil.h"
 #include "string.h"
+#include <stdlib.h>
+
+SHP_CVSID("$Id: shputils.c,v 1.10 2007-12-13 19:59:23 fwarmerdam Exp $")
+
 #ifndef FALSE
 #  define FALSE		0
 #  define TRUE		1
@@ -112,9 +122,10 @@ char	iszFormat[32], iszField[1024];
 char	jszFormat[32], jszField[1024];
 int	i, ti, iWidth, iDecimals, iRecord;
 int	j, tj, jWidth, jDecimals, jRecord;
-int     found, newdbf;
 
 
+int clip_boundary();
+double findunit(char *unit);
 void openfiles(void);
 void setext(char *pt, char *ext);
 int strncasecmp2(char *s1, char *s2, int n);
@@ -122,7 +133,7 @@ void mergefields(void);
 void findselect(void);
 void showitems(void);
 int selectrec();
-int check_theme_bnd();
+void check_theme_bnd();
 int clip_boundary();
 void error();
 
@@ -257,7 +268,7 @@ int main( int argc, char ** argv )
                 iclip=TRUE;
             } /*** End CLIP & ERASE ***/
             else if (strncasecmp2(argv[i],  "FACTOR",0) == 0)
-                {
+            {
                 i++;
     	        if (i >= argc) error();
     	        infactor=findunit(argv[i]);
@@ -268,20 +279,20 @@ int main( int argc, char ** argv )
     	        outfactor=findunit(argv[i]);
     	        if (outfactor == 0)
     	        {
-                   sscanf(argv[i],"%lf",&factor);
-                   if (factor == 0) error();
+                    sscanf(argv[i],"%lf",&factor);
+                    if (factor == 0) error();
                 }
                 if (factor == 0)
                 {
-                  if (infactor ==0)
-                  { puts("ERROR: Input unit must be defined before output unit"); exit(); }
-                  factor=infactor/outfactor;
+                    if (infactor ==0)
+                    { puts("ERROR: Input unit must be defined before output unit"); exit(1); }
+                    factor=infactor/outfactor;
                 }
                 printf("Output file coordinate values will be factored by %lg\n",factor);
                 ifactor=(factor != 1); /* True if a valid factor */
-             } /*** End FACTOR ***/
-             else if (strncasecmp2(argv[i],"SHIFT",5) == 0)
-                {
+            } /*** End FACTOR ***/
+            else if (strncasecmp2(argv[i],"SHIFT",5) == 0)
+            {
                 i++;
                 if (i >= argc) error();
                 sscanf(argv[i],"%lf",&xshift);
@@ -290,10 +301,10 @@ int main( int argc, char ** argv )
                 sscanf(argv[i],"%lf",&yshift);
                 iunit=TRUE;
                 printf("X Shift: %lg   Y Shift: %lg\n",xshift,yshift);
-             } /*** End SHIFT ***/
-             else {
+            } /*** End SHIFT ***/
+            else {
                 printf("ERROR: Unknown function %s\n",argv[i]);  error();
-                }
+            }
     }
 /* -------------------------------------------------------------------- */
 /*	If there is no data in this file let the user know.		*/
@@ -380,6 +391,7 @@ int main( int argc, char ** argv )
                 switch( DBFGetFieldInfo( hDBF, i, NULL, &iWidth, &iDecimals ) )
                 {
                   case FTString:
+                  case FTLogical:
                     DBFWriteStringAttribute(hDBFappend, jRecord, pt[i],
                                             (DBFReadStringAttribute( hDBF, iRecord, i )) );
                     break;
@@ -393,6 +405,9 @@ int main( int argc, char ** argv )
                     DBFWriteDoubleAttribute(hDBFappend, jRecord, pt[i],
                                             (DBFReadDoubleAttribute( hDBF, iRecord, i )) );
                     break;
+
+                  case FTInvalid:
+                    break;
                 }
             }
 	}
@@ -400,7 +415,7 @@ int main( int argc, char ** argv )
 /* -------------------------------------------------------------------- */
 /*      Change FACTOR and SHIFT coordinates of shapes if needed.        */
 /* -------------------------------------------------------------------- */
-         if (iunit)
+        if (iunit)
         {
 	    for( j = 0; j < psCShape->nVertices; j++ ) 
 	    {
@@ -441,13 +456,13 @@ int main( int argc, char ** argv )
     DBFClose( hDBF );
     DBFClose( hDBFappend );
     if (nEntitiesAppend == 0) {
-       puts("Remove the output files.");
-       setext(outfile, "dbf");
-       remove(outfile);
-       setext(outfile, "shp");
-       remove(outfile);
-       setext(outfile, "shx");
-       remove(outfile);
+        puts("Remove the output files.");
+        setext(outfile, "dbf");
+        remove(outfile);
+        setext(outfile, "shp");
+        remove(outfile);
+        setext(outfile, "shx");
+        remove(outfile);
     }
     return( 0 );
 }
@@ -562,7 +577,7 @@ void mergefields()
     
     for( i = 0; i < ti; i++ )
     {
-       pt[i]= -1;  /* Initial pt values to -1 */
+        pt[i]= -1;  /* Initial pt values to -1 */
     }
     /* DBF must be empty before adding items */
     jRecord = DBFGetRecordCount( hDBFappend );
@@ -607,7 +622,7 @@ void mergefields()
                 == -1 )
 	    {
 		printf( "Warning: DBFAddField(%s, TYPE:%d, WIDTH:%d  DEC:%d, ITEM#:%d of %d) failed.\n",
-		         iszTitle, iType, iWidth, iDecimals, (i+1), (ti+1) );
+                        iszTitle, iType, iWidth, iDecimals, (i+1), (ti+1) );
 		pt[i]=-1;
 	    }
 	}
@@ -638,92 +653,96 @@ void findselect()
 
 void showitems()
 {
-char      stmp[40],slow[40],shigh[40];
-double    dtmp,dlow,dhigh,dsum,mean;
-long int  itmp,ilow,ihigh,isum;
-long int  maxrec;
-char      *pt;
-
-        printf("Available Items: (%d)",ti);
-        maxrec = DBFGetRecordCount(hDBF);
-        if (maxrec > 5000 && ! iall) 
-                { maxrec=5000; printf("  ** ESTIMATED RANGES (MEAN)  For more records use \"All\""); }
-          else  { printf("          RANGES (MEAN)"); }
+    char      stmp[40],slow[40],shigh[40];
+    double    dtmp,dlow,dhigh,dsum,mean;
+    long int  itmp,ilow,ihigh,isum;
+    long int  maxrec;
+    char      *pt;
+
+    printf("Available Items: (%d)",ti);
+    maxrec = DBFGetRecordCount(hDBF);
+    if (maxrec > 5000 && ! iall) 
+    { maxrec=5000; printf("  ** ESTIMATED RANGES (MEAN)  For more records use \"All\""); }
+    else  { printf("          RANGES (MEAN)"); }
           
-        for( i = 0; i < ti; i++ )
+    for( i = 0; i < ti; i++ )
+    {
+        switch( DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ) )
         {
-	    switch( DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ) )
-	    {
-	      case FTString:
-	        strcpy(slow, "~");
-	        strcpy(shigh,"\0");
-                printf("\n  String  %3d  %-16s",iWidth,iszTitle);
-	        for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
-		        strncpy(stmp,DBFReadStringAttribute( hDBF, iRecord, i ),39);
-		        if (strcmp(stmp,"!!") > 0) {
-		          if (strncasecmp2(stmp,slow,0)  < 0) strncpy(slow, stmp,39);
-		          if (strncasecmp2(stmp,shigh,0) > 0) strncpy(shigh,stmp,39);
-		        }
-		}
-		pt=slow+strlen(slow)-1; 
-		while(*pt == ' ') { *pt='\0'; pt--; }
-		pt=shigh+strlen(shigh)-1;
-		while(*pt == ' ') { *pt='\0'; pt--; }
-		if (strncasecmp2(slow,shigh,0) < 0)		printf("%s to %s",slow,shigh);
-		else if (strncasecmp2(slow,shigh,0) == 0)	printf("= %s",slow);
-						    else	printf("No Values");
-		break;
-	      case FTInteger:
-		printf("\n  Integer %3d  %-16s",iWidth,iszTitle);
-		ilow =  1999999999;
-		ihigh= -1999999999;
-		isum =  0;
-	        for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
-		        itmp = DBFReadIntegerAttribute( hDBF, iRecord, i );
-		        if (ilow > itmp)  ilow = itmp;
-		        if (ihigh < itmp) ihigh = itmp;
-		        isum = isum + itmp;
-		}
-		mean=isum/maxrec;
-		if (ilow < ihigh)       printf("%d to %d \t(%.1f)",ilow,ihigh,mean);
-		else if (ilow == ihigh) printf("= %d",ilow);
-		                   else printf("No Values");
-		break;
-
-	      case FTDouble:
-		printf("\n  Real  %3d,%d  %-16s",iWidth,iDecimals,iszTitle);
-		dlow =  999999999999999.0;
-		dhigh= -999999999999999.0;
-		dsum =  0;
-	        for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
-		        dtmp = DBFReadDoubleAttribute( hDBF, iRecord, i );
-		        if (dlow > dtmp) dlow = dtmp;
-		        if (dhigh < dtmp) dhigh = dtmp;
-		        dsum = dsum + dtmp;
-		}
-		mean=dsum/maxrec;
-		sprintf(stmp,"%%.%df to %%.%df \t(%%.%df)",iDecimals,iDecimals,iDecimals);
-		if (dlow < dhigh)       printf(stmp,dlow,dhigh,mean);
-		else if (dlow == dhigh) {
-				        sprintf(stmp,"= %%.%df",iDecimals);
-		                        printf(stmp,dlow);
-		                        }
-		else printf("No Values");
-		break;
+          case FTString:
+          case FTLogical:
+            strcpy(slow, "~");
+            strcpy(shigh,"\0");
+            printf("\n  String  %3d  %-16s",iWidth,iszTitle);
+            for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
+                strncpy(stmp,DBFReadStringAttribute( hDBF, iRecord, i ),39);
+                if (strcmp(stmp,"!!") > 0) {
+                    if (strncasecmp2(stmp,slow,0)  < 0) strncpy(slow, stmp,39);
+                    if (strncasecmp2(stmp,shigh,0) > 0) strncpy(shigh,stmp,39);
+                }
+            }
+            pt=slow+strlen(slow)-1; 
+            while(*pt == ' ') { *pt='\0'; pt--; }
+            pt=shigh+strlen(shigh)-1;
+            while(*pt == ' ') { *pt='\0'; pt--; }
+            if (strncasecmp2(slow,shigh,0) < 0)		printf("%s to %s",slow,shigh);
+            else if (strncasecmp2(slow,shigh,0) == 0)	printf("= %s",slow);
+            else	printf("No Values");
+            break;
+          case FTInteger:
+            printf("\n  Integer %3d  %-16s",iWidth,iszTitle);
+            ilow =  1999999999;
+            ihigh= -1999999999;
+            isum =  0;
+            for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
+                itmp = DBFReadIntegerAttribute( hDBF, iRecord, i );
+                if (ilow > itmp)  ilow = itmp;
+                if (ihigh < itmp) ihigh = itmp;
+                isum = isum + itmp;
+            }
+            mean=isum/maxrec;
+            if (ilow < ihigh)       printf("%ld to %ld \t(%.1f)",ilow,ihigh,mean);
+            else if (ilow == ihigh) printf("= %ld",ilow);
+            else printf("No Values");
+            break;
 
-	    }
+          case FTDouble:
+            printf("\n  Real  %3d,%d  %-16s",iWidth,iDecimals,iszTitle);
+            dlow =  999999999999999.0;
+            dhigh= -999999999999999.0;
+            dsum =  0;
+            for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
+                dtmp = DBFReadDoubleAttribute( hDBF, iRecord, i );
+                if (dlow > dtmp) dlow = dtmp;
+                if (dhigh < dtmp) dhigh = dtmp;
+                dsum = dsum + dtmp;
+            }
+            mean=dsum/maxrec;
+            sprintf(stmp,"%%.%df to %%.%df \t(%%.%df)",iDecimals,iDecimals,iDecimals);
+            if (dlow < dhigh)       printf(stmp,dlow,dhigh,mean);
+            else if (dlow == dhigh) {
+                sprintf(stmp,"= %%.%df",iDecimals);
+                printf(stmp,dlow);
+            }
+            else printf("No Values");
+            break;
+
+          case FTInvalid:
+            break;
 
         }
-	printf("\n");
+
+    }
+    printf("\n");
 }
 
 int selectrec()
 {
-long int value, ty;
+    long int value, ty;
 
-   ty = DBFGetFieldInfo( hDBF, iselectitem, NULL, &iWidth, &iDecimals);
-      switch(ty)
-      {
+    ty = DBFGetFieldInfo( hDBF, iselectitem, NULL, &iWidth, &iDecimals);
+    switch(ty)
+    {
       case FTString:
         puts("Invalid Item");
         iselect=FALSE;
@@ -731,23 +750,25 @@ long int value, ty;
       case FTInteger:
         value = DBFReadIntegerAttribute( hDBF, iRecord, iselectitem );
         for (j = 0; j<selcount; j++)
-          {
-          if (selectvalues[j] == value)
-               if (iunselect) return(0);  /* Keep this record */
-                        else  return(1);  /* Skip this record */
-          }
+        {
+            if (selectvalues[j] == value)
+            {
+                if (iunselect) return(0);  /* Keep this record */
+                else  return(1);  /* Skip this record */
+            }
+        }
 	break;
       case FTDouble:
         puts("Invalid Item");
         iselect=FALSE;
         break;
-      }
-      if (iunselect) return(1);  /* Skip this record */
-               else  return(0);  /* Keep this record */
+    }
+    if (iunselect) return(1);  /* Skip this record */
+    else  return(0);  /* Keep this record */
 }
 
 
-int check_theme_bnd()
+void check_theme_bnd()
 {
     if ( (adfBoundsMin[0] >= cxmin) && (adfBoundsMax[0] <= cxmax) &&
          (adfBoundsMin[1] >= cymin) && (adfBoundsMax[1] <= cymax) )
@@ -769,111 +790,113 @@ int check_theme_bnd()
         puts("WARNING: Theme is outside the clip area."); /** SKIP THEME  **/
 }
 
-clip_boundary()
+int clip_boundary()
 {
     int  inside;
     int  prev_outside;
     int  i2;
     int  j2;
     
-       /*** FIRST check the boundary of the feature ***/
-       if ( ( (psCShape->dfXMin < cxmin) && (psCShape->dfXMax < cxmin) ) ||
-            ( (psCShape->dfYMin < cymin) && (psCShape->dfYMax < cymin) ) ||
-            ( (psCShape->dfXMin > cxmax) && (psCShape->dfXMax > cxmax) ) ||
-            ( (psCShape->dfYMin > cymax) && (psCShape->dfYMax > cymax) ) )
-            {   /** Feature is totally outside clip area **/
-            	if (ierase) return(1); /** WRITE RECORD **/
-            	     else   return(0); /** SKIP  RECORD **/
-            }
+    /*** FIRST check the boundary of the feature ***/
+    if ( ( (psCShape->dfXMin < cxmin) && (psCShape->dfXMax < cxmin) ) ||
+         ( (psCShape->dfYMin < cymin) && (psCShape->dfYMax < cymin) ) ||
+         ( (psCShape->dfXMin > cxmax) && (psCShape->dfXMax > cxmax) ) ||
+         ( (psCShape->dfYMin > cymax) && (psCShape->dfYMax > cymax) ) )
+    {   /** Feature is totally outside clip area **/
+        if (ierase) return(1); /** WRITE RECORD **/
+        else   return(0); /** SKIP  RECORD **/
+    }
        
-       if ( (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax) &&
-            (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax) )
-            {   /** Feature is totally inside clip area **/
-            	if (ierase) return(0); /** SKIP  RECORD **/
-            	     else   return(1); /** WRITE RECORD **/
-            }
+    if ( (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax) &&
+         (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax) )
+    {   /** Feature is totally inside clip area **/
+        if (ierase) return(0); /** SKIP  RECORD **/
+        else   return(1); /** WRITE RECORD **/
+    }
             
-       if (iinside) 
-            { /** INSIDE * Feature might touch the boundary or could be outside **/
-            if (ierase)  return(1); /** WRITE RECORD **/
-                 else    return(0); /** SKIP  RECORD **/
-            }
+    if (iinside) 
+    { /** INSIDE * Feature might touch the boundary or could be outside **/
+        if (ierase)  return(1); /** WRITE RECORD **/
+        else    return(0); /** SKIP  RECORD **/
+    }
        
-       if (itouch)
-          {   /** TOUCH **/
-          if ( ( (psCShape->dfXMin <= cxmin) || (psCShape->dfXMax >= cxmax) ) && 
-                 (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax)    )
-               {   /** Feature intersects the clip boundary only on the X axis **/
-               if (ierase) return(0); /** SKIP  RECORD **/
-                    else   return(1); /** WRITE RECORD **/
-               }
-
-          if (   (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax)   && 
+    if (itouch)
+    {   /** TOUCH **/
+        if ( ( (psCShape->dfXMin <= cxmin) || (psCShape->dfXMax >= cxmax) ) && 
+             (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax)    )
+        {   /** Feature intersects the clip boundary only on the X axis **/
+            if (ierase) return(0); /** SKIP  RECORD **/
+            else   return(1); /** WRITE RECORD **/
+        }
+
+        if (   (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax)   && 
                ( (psCShape->dfYMin <= cymin) || (psCShape->dfYMax >= cymax) )  )
-               {   /** Feature intersects the clip boundary only on the Y axis **/
-               if (ierase) return(0); /** SKIP  RECORD **/
-                    else   return(1); /** WRITE RECORD **/
-               }
+        {   /** Feature intersects the clip boundary only on the Y axis **/
+            if (ierase) return(0); /** SKIP  RECORD **/
+            else   return(1); /** WRITE RECORD **/
+        }
                
-          for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
-               {   /** At least one vertex must be inside the clip boundary **/
-               if ( (psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax) ||
-                    (psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax)  )
-                    if (ierase) return(0); /** SKIP  RECORD **/
-                         else   return(1); /** WRITE RECORD **/
-               }
+        for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
+        {   /** At least one vertex must be inside the clip boundary **/
+            if ( (psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax) ||
+                 (psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax)  )
+            {
+                if (ierase) return(0); /** SKIP  RECORD **/
+                else   return(1); /** WRITE RECORD **/
+            }
+        }
                
-          /** All vertices are outside the clip boundary **/ 
-          if (ierase) return(1); /** WRITE RECORD **/
-               else   return(0); /** SKIP  RECORD **/
-          }   /** End TOUCH **/
+        /** All vertices are outside the clip boundary **/ 
+        if (ierase) return(1); /** WRITE RECORD **/
+        else   return(0); /** SKIP  RECORD **/
+    }   /** End TOUCH **/
           
-       if (icut)
-          {   /** CUT **/
-          /*** Check each vertex in the feature with the Boundary and "CUT" ***/
-          /*** THIS CODE WAS NOT COMPLETED!  READ NOTE AT THE BOTTOM ***/
-          i2=0;
-          prev_outside=FALSE;
-          for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
-             {
-             inside = psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax  &&
-                      psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax ;
+    if (icut)
+    {   /** CUT **/
+        /*** Check each vertex in the feature with the Boundary and "CUT" ***/
+        /*** THIS CODE WAS NOT COMPLETED!  READ NOTE AT THE BOTTOM ***/
+        i2=0;
+        prev_outside=FALSE;
+        for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
+        {
+            inside = psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax  &&
+                psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax ;
                       
-             if (ierase) inside=(! inside);
-             if (inside)
-                 {
-                 if (i2 != j2)
-                     {
-                     if (prev_outside)
-                         {
-                         /*** AddIntersection(i2);   /*** Add intersection ***/
-                         prev_outside=FALSE;
-                         }
-                     psCShape->padfX[i2]=psCShape->padfX[j2];     /** move vertex **/
-                     psCShape->padfY[i2]=psCShape->padfY[j2];
-                     }
-                 i2++;
-                 } else {
-                 if ( (! prev_outside) && (j2 > 0) )
-                     {
-                     /*** AddIntersection(i2);   /*** Add intersection (Watch out for j2==i2-1) ***/
-                     /*** Also a polygon may overlap twice and will split into a several parts  ***/
-                     prev_outside=TRUE;
-                     }
-                 }
-             }
+            if (ierase) inside=(! inside);
+            if (inside)
+            {
+                if (i2 != j2)
+                {
+                    if (prev_outside)
+                    {
+                        /*** AddIntersection(i2); ***/  /*** Add intersection ***/
+                        prev_outside=FALSE;
+                    }
+                    psCShape->padfX[i2]=psCShape->padfX[j2];     /** move vertex **/
+                    psCShape->padfY[i2]=psCShape->padfY[j2];
+                }
+                i2++;
+            } else {
+                if ( (! prev_outside) && (j2 > 0) )
+                {
+                    /*** AddIntersection(i2); ***//*** Add intersection (Watch out for j2==i2-1) ***/
+                    /*** Also a polygon may overlap twice and will split into a several parts  ***/
+                    prev_outside=TRUE;
+                }
+            }
+        }
              
         printf("Vertices:%d   OUT:%d   Number of Parts:%d\n",
-                psCShape->nVertices,i2, psCShape->nParts );
+               psCShape->nVertices,i2, psCShape->nParts );
                
-             psCShape->nVertices = i2;
+        psCShape->nVertices = i2;
              
-             if (i2 < 2) return(0); /** SKIP RECORD **/
-             /*** (WE ARE NOT CREATING INTERESECTIONS and some lines could be reduced to one point) **/
+        if (i2 < 2) return(0); /** SKIP RECORD **/
+        /*** (WE ARE NOT CREATING INTERESECTIONS and some lines could be reduced to one point) **/
         
-             if (i2 == 0) return(0); /** SKIP  RECORD **/
-                  else    return(1); /** WRITE RECORD **/
-          }  /** End CUT **/
+        if (i2 == 0) return(0); /** SKIP  RECORD **/
+        else    return(1); /** WRITE RECORD **/
+    }  /** End CUT **/
 }
 
 
@@ -910,8 +933,7 @@ int j,i;
 
 
 #define  NKEYS (sizeof(unitkeytab) / sizeof(struct unitkey))
-findunit(unit)
-   char *unit;
+double findunit(char *unit)
    {
    struct unitkey {
      char   *name;
@@ -946,65 +968,65 @@ findunit(unit)
 /*      Display a usage message.                                        */
 /* -------------------------------------------------------------------- */
 void error()
-    {	
-	puts( "The program will append to an existing shape file or it will" );
-	puts( "create a new file if needed." );
-	puts( "Only the items in the first output file will be preserved." );
-	puts( "When an item does not match with the append theme then the item");
-	puts( "might be placed to an existing item at the same position and type." );
-	puts( "  OTHER FUNCTIONS:" );
-	puts( "  - Describe all items in the dbase file (Use ALL for more than 5000 recs.)");
-	puts( "  - Select a group of shapes from a comma separated selection list.");
-	puts( "  - UnSelect a group of shapes from a comma separated selection list.");
-	puts( "  - Clip boundary extent or by theme boundary." );
-	puts( "      Touch writes all the shapes that touch the boundary.");
-	puts( "      Inside writes all the shapes that are completely within the boundary.");
-	puts( "      Boundary clips are only the min and max of a theme boundary." );
-	puts( "  - Erase boundary extent or by theme boundary." );
-	puts( "      Erase is the direct opposite of the Clip function." );
-	puts( "  - Change coordinate value units between meters and feet.");
-	puts( "      There is no way to determine the input unit of a shape file.");
-	puts( "      Skip this function if the shape file is already in the correct unit.");
-	puts( "      Clip and Erase will be done before the unit is changed.");
-	puts( "      A shift will be done after the unit is changed."); 
-	puts( "  - Shift X and Y coordinates.\n" );
-	puts( "Finally, There can only be one select or unselect in the command line.");
-	puts( "         There can only be one clip or erase in the command line.");
-	puts( "         There can only be one unit and only one shift in the command line.\n");
-	puts( "Ex: shputils in.shp out.shp   SELECT countycode 3,5,9,13,17,27");
-	puts( "    shputils in.shp out.shp   CLIP   10 10 90 90 Touch   FACTOR Meter Feet");
-	puts( "    shputils in.shp out.shp   FACTOR Meter 3.0");
-	puts( "    shputils in.shp out.shp   CLIP   clip.shp Boundary Touch   SHIFT 40 40");
-	puts( "    shputils in.shp out.shp   SELECT co 112   CLIP clip.shp Boundary Touch\n");
-	puts( "USAGE: shputils  <DescribeShape>   {ALL}");
-	puts( "USAGE: shputils  <InputShape>  <OutShape|AppendShape>" );
-	puts( "   { <FACTOR>       <FEET|MILES|METERS|KM> <FEET|MILES|METERS|KM|factor> }" );
-	puts( "   { <SHIFT>        <xshift> <yshift> }" );
-	puts( "   { <SELECT|UNSEL> <Item> <valuelist> }" );
-	puts( "   { <CLIP|ERASE>   <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
-	puts( "   { <CLIP|ERASE>   <theme>      <BOUNDARY>     <TOUCH|INSIDE|CUT> }" );
-	puts( "     Note: CUT is not complete and does not create intersections.");
-	puts( "           For more information read programmer comment.");
+{	
+    puts( "The program will append to an existing shape file or it will" );
+    puts( "create a new file if needed." );
+    puts( "Only the items in the first output file will be preserved." );
+    puts( "When an item does not match with the append theme then the item");
+    puts( "might be placed to an existing item at the same position and type." );
+    puts( "  OTHER FUNCTIONS:" );
+    puts( "  - Describe all items in the dbase file (Use ALL for more than 5000 recs.)");
+    puts( "  - Select a group of shapes from a comma separated selection list.");
+    puts( "  - UnSelect a group of shapes from a comma separated selection list.");
+    puts( "  - Clip boundary extent or by theme boundary." );
+    puts( "      Touch writes all the shapes that touch the boundary.");
+    puts( "      Inside writes all the shapes that are completely within the boundary.");
+    puts( "      Boundary clips are only the min and max of a theme boundary." );
+    puts( "  - Erase boundary extent or by theme boundary." );
+    puts( "      Erase is the direct opposite of the Clip function." );
+    puts( "  - Change coordinate value units between meters and feet.");
+    puts( "      There is no way to determine the input unit of a shape file.");
+    puts( "      Skip this function if the shape file is already in the correct unit.");
+    puts( "      Clip and Erase will be done before the unit is changed.");
+    puts( "      A shift will be done after the unit is changed."); 
+    puts( "  - Shift X and Y coordinates.\n" );
+    puts( "Finally, There can only be one select or unselect in the command line.");
+    puts( "         There can only be one clip or erase in the command line.");
+    puts( "         There can only be one unit and only one shift in the command line.\n");
+    puts( "Ex: shputils in.shp out.shp   SELECT countycode 3,5,9,13,17,27");
+    puts( "    shputils in.shp out.shp   CLIP   10 10 90 90 Touch   FACTOR Meter Feet");
+    puts( "    shputils in.shp out.shp   FACTOR Meter 3.0");
+    puts( "    shputils in.shp out.shp   CLIP   clip.shp Boundary Touch   SHIFT 40 40");
+    puts( "    shputils in.shp out.shp   SELECT co 112   CLIP clip.shp Boundary Touch\n");
+    puts( "USAGE: shputils  <DescribeShape>   {ALL}");
+    puts( "USAGE: shputils  <InputShape>  <OutShape|AppendShape>" );
+    puts( "   { <FACTOR>       <FEET|MILES|METERS|KM> <FEET|MILES|METERS|KM|factor> }" );
+    puts( "   { <SHIFT>        <xshift> <yshift> }" );
+    puts( "   { <SELECT|UNSEL> <Item> <valuelist> }" );
+    puts( "   { <CLIP|ERASE>   <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
+    puts( "   { <CLIP|ERASE>   <theme>      <BOUNDARY>     <TOUCH|INSIDE|CUT> }" );
+    puts( "     Note: CUT is not complete and does not create intersections.");
+    puts( "           For more information read programmer comment.");
 	
-	/****   Clip functions for Polygon and Cut is not supported
-	There are several web pages that describe methods of doing this function.
-	It seem easy to impliment until you start writting code.  I don't have the
-	time to add these functions but a did leave a simple cut routine in the 
-	program that can be called by using CUT instead of TOUCH in the 
-	CLIP or ERASE functions.  It does not add the intersection of the line and
-	the clip box, so polygons could look incomplete and lines will come up short.
+    /****   Clip functions for Polygon and Cut is not supported
+            There are several web pages that describe methods of doing this function.
+            It seem easy to impliment until you start writting code.  I don't have the
+            time to add these functions but a did leave a simple cut routine in the 
+            program that can be called by using CUT instead of TOUCH in the 
+            CLIP or ERASE functions.  It does not add the intersection of the line and
+            the clip box, so polygons could look incomplete and lines will come up short.
 	
-	Information about clipping lines with a box:
-           http://www.csclub.uwaterloo.ca/u/mpslager/articles/sutherland/wr.html
-        Information about finding the intersection of two lines:
-	   http://www.whisqu.se/per/docs/math28.htm
+            Information about clipping lines with a box:
+            http://www.csclub.uwaterloo.ca/u/mpslager/articles/sutherland/wr.html
+            Information about finding the intersection of two lines:
+            http://www.whisqu.se/per/docs/math28.htm
 	   
-THE CODE LOOKS LIKE THIS:
- ********************************************************	  
-void Intersect_Lines(float x0,float y0,float x1,float y1,
-                     float x2,float y2,float x3,float y3,
-                     float *xi,float *yi)
-                     {
+            THE CODE LOOKS LIKE THIS:
+            ********************************************************	  
+            void Intersect_Lines(float x0,float y0,float x1,float y1,
+            float x2,float y2,float x3,float y3,
+            float *xi,float *yi)
+            {
 //  this function computes the intersection of the sent lines
 //  and returns the intersection point, note that the function assumes
 //  the lines intersect. the function can handle vertical as well
@@ -1014,22 +1036,22 @@ void Intersect_Lines(float x0,float y0,float x1,float y1,
 //  The Intersect_lines program came from (http://www.whisqu.se/per/docs/math28.htm)
 
 float a1,b1,c1, // constants of linear equations 
-      a2,b2,c2,
-      det_inv,  // the inverse of the determinant of the coefficientmatrix
-      m1,m2;    // the slopes of each line
+a2,b2,c2,
+det_inv,  // the inverse of the determinant of the coefficientmatrix
+m1,m2;    // the slopes of each line
       
 // compute slopes, note the cludge for infinity, however, this will
 // be close enough
 if ((x1-x0)!=0)
-   m1 = (y1-y0)/(x1-x0);
+m1 = (y1-y0)/(x1-x0);
 else
-   m1 = (float)1e+10;  // close enough to infinity
+m1 = (float)1e+10;  // close enough to infinity
    
    
 if ((x3-x2)!=0) 
-   m2 = (y3-y2)/(x3-x2);
+m2 = (y3-y2)/(x3-x2);
 else
-   m2 = (float)1e+10;  // close enough to infinity
+m2 = (float)1e+10;  // close enough to infinity
    
 // compute constants
 a1 = m1;
@@ -1044,7 +1066,7 @@ det_inv = 1/(a1*b2 - a2*b1);
 *xi=((b1*c2 - b2*c1)*det_inv);
 *yi=((a2*c1 - a1*c2)*det_inv);
 } // end Intersect_Lines
- **********************************************************/
+    **********************************************************/
 
-	exit( 1 );
-    }
+    exit( 1 );
+}
diff --git a/stream2.out b/stream2.out
index 424a9e6..249f8b8 100644
--- a/stream2.out
+++ b/stream2.out
@@ -3,528 +3,528 @@ Test 2/0
 -----------------------------------------------------------------------
 Shapefile Type: NullShape   # of Shapes: 2
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (      10.000,      20.000,0,0)
+File Bounds: (0,0,0,0)
+         to  (10,20,0,0)
 
 Shape:0 (NullShape)  nVertices=0, nParts=0
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (       0.000,       0.000, 0, 0)
+  Bounds:(0,0, 0)
+      to (0,0, 0)
 
 Shape:1 (NullShape)  nVertices=0, nParts=0
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (       0.000,       0.000, 0, 0)
+  Bounds:(0,0, 0)
+      to (0,0, 0)
 -----------------------------------------------------------------------
 Test 2/1
 -----------------------------------------------------------------------
 Shapefile Type: Point   # of Shapes: 2
 
-File Bounds: (       1.000,       2.000,0,0)
-         to  (      10.000,      20.000,0,0)
+File Bounds: (1,2,0,0)
+         to  (10,20,0,0)
 
 Shape:0 (Point)  nVertices=1, nParts=0
-  Bounds:(       1.000,       2.000, 0, 0)
-      to (       1.000,       2.000, 0, 0)
-     (       1.000,       2.000, 0, 0)  
+  Bounds:(1,2, 0)
+      to (1,2, 0)
+     (1,2, 0)  
 
 Shape:1 (Point)  nVertices=1, nParts=0
-  Bounds:(      10.000,      20.000, 0, 0)
-      to (      10.000,      20.000, 0, 0)
-     (      10.000,      20.000, 0, 0)  
+  Bounds:(10,20, 0)
+      to (10,20, 0)
+     (10,20, 0)  
 -----------------------------------------------------------------------
 Test 2/2
 -----------------------------------------------------------------------
 Shapefile Type: PointZ   # of Shapes: 2
 
-File Bounds: (       1.000,       2.000,3,4)
-         to  (      10.000,      20.000,30,40)
+File Bounds: (1,2,3,4)
+         to  (10,20,30,40)
 
 Shape:0 (PointZ)  nVertices=1, nParts=0
-  Bounds:(       1.000,       2.000, 3, 4)
-      to (       1.000,       2.000, 3, 4)
-     (       1.000,       2.000, 3, 4)  
+  Bounds:(1,2, 3, 4)
+      to (1,2, 3, 4)
+     (1,2, 3, 4)  
 
 Shape:1 (PointZ)  nVertices=1, nParts=0
-  Bounds:(      10.000,      20.000, 30, 40)
-      to (      10.000,      20.000, 30, 40)
-     (      10.000,      20.000, 30, 40)  
+  Bounds:(10,20, 30, 40)
+      to (10,20, 30, 40)
+     (10,20, 30, 40)  
 -----------------------------------------------------------------------
 Test 2/3
 -----------------------------------------------------------------------
 Shapefile Type: PointM   # of Shapes: 2
 
-File Bounds: (       1.000,       2.000,0,4)
-         to  (      10.000,      20.000,0,40)
+File Bounds: (1,2,0,4)
+         to  (10,20,0,40)
 
 Shape:0 (PointM)  nVertices=1, nParts=0
-  Bounds:(       1.000,       2.000, 0, 4)
-      to (       1.000,       2.000, 0, 4)
-     (       1.000,       2.000, 0, 4)  
+  Bounds:(1,2, 0, 4)
+      to (1,2, 0, 4)
+     (1,2, 0, 4)  
 
 Shape:1 (PointM)  nVertices=1, nParts=0
-  Bounds:(      10.000,      20.000, 0, 40)
-      to (      10.000,      20.000, 0, 40)
-     (      10.000,      20.000, 0, 40)  
+  Bounds:(10,20, 0, 40)
+      to (10,20, 0, 40)
+     (10,20, 0, 40)  
 -----------------------------------------------------------------------
 Test 2/4
 -----------------------------------------------------------------------
 Shapefile Type: MultiPoint   # of Shapes: 3
 
-File Bounds: (       1.150,       2.250,0,0)
-         to  (      24.150,      25.250,0,0)
+File Bounds: (1.15,2.25,0,0)
+         to  (24.15,25.25,0,0)
 
 Shape:0 (MultiPoint)  nVertices=4, nParts=0
-  Bounds:(       1.150,       2.250, 0, 0)
-      to (       4.150,       5.250, 0, 0)
-     (       1.150,       2.250, 0, 0)  
-     (       2.150,       3.250, 0, 0)  
-     (       3.150,       4.250, 0, 0)  
-     (       4.150,       5.250, 0, 0)  
+  Bounds:(1.15,2.25, 0)
+      to (4.15,5.25, 0)
+     (1.15,2.25, 0)  
+     (2.15,3.25, 0)  
+     (3.15,4.25, 0)  
+     (4.15,5.25, 0)  
 
 Shape:1 (MultiPoint)  nVertices=4, nParts=0
-  Bounds:(      11.150,      12.250, 0, 0)
-      to (      14.150,      15.250, 0, 0)
-     (      11.150,      12.250, 0, 0)  
-     (      12.150,      13.250, 0, 0)  
-     (      13.150,      14.250, 0, 0)  
-     (      14.150,      15.250, 0, 0)  
+  Bounds:(11.15,12.25, 0)
+      to (14.15,15.25, 0)
+     (11.15,12.25, 0)  
+     (12.15,13.25, 0)  
+     (13.15,14.25, 0)  
+     (14.15,15.25, 0)  
 
 Shape:2 (MultiPoint)  nVertices=4, nParts=0
-  Bounds:(      21.150,      22.250, 0, 0)
-      to (      24.150,      25.250, 0, 0)
-     (      21.150,      22.250, 0, 0)  
-     (      22.150,      23.250, 0, 0)  
-     (      23.150,      24.250, 0, 0)  
-     (      24.150,      25.250, 0, 0)  
+  Bounds:(21.15,22.25, 0)
+      to (24.15,25.25, 0)
+     (21.15,22.25, 0)  
+     (22.15,23.25, 0)  
+     (23.15,24.25, 0)  
+     (24.15,25.25, 0)  
 -----------------------------------------------------------------------
 Test 2/5
 -----------------------------------------------------------------------
 Shapefile Type: MultiPointZ   # of Shapes: 3
 
-File Bounds: (       1.150,       2.250,3.35,4.45)
-         to  (      24.150,      25.250,26.35,27.45)
+File Bounds: (1.15,2.25,3.35,4.45)
+         to  (24.15,25.25,26.35,27.45)
 
 Shape:0 (MultiPointZ)  nVertices=4, nParts=0
-  Bounds:(       1.150,       2.250, 3.35, 4.45)
-      to (       4.150,       5.250, 6.35, 7.45)
-     (       1.150,       2.250, 3.35, 4.45)  
-     (       2.150,       3.250, 4.35, 5.45)  
-     (       3.150,       4.250, 5.35, 6.45)  
-     (       4.150,       5.250, 6.35, 7.45)  
+  Bounds:(1.15,2.25, 3.35, 4.45)
+      to (4.15,5.25, 6.35, 7.45)
+     (1.15,2.25, 3.35, 4.45)  
+     (2.15,3.25, 4.35, 5.45)  
+     (3.15,4.25, 5.35, 6.45)  
+     (4.15,5.25, 6.35, 7.45)  
 
 Shape:1 (MultiPointZ)  nVertices=4, nParts=0
-  Bounds:(      11.150,      12.250, 13.35, 14.45)
-      to (      14.150,      15.250, 16.35, 17.45)
-     (      11.150,      12.250, 13.35, 14.45)  
-     (      12.150,      13.250, 14.35, 15.45)  
-     (      13.150,      14.250, 15.35, 16.45)  
-     (      14.150,      15.250, 16.35, 17.45)  
+  Bounds:(11.15,12.25, 13.35, 14.45)
+      to (14.15,15.25, 16.35, 17.45)
+     (11.15,12.25, 13.35, 14.45)  
+     (12.15,13.25, 14.35, 15.45)  
+     (13.15,14.25, 15.35, 16.45)  
+     (14.15,15.25, 16.35, 17.45)  
 
 Shape:2 (MultiPointZ)  nVertices=4, nParts=0
-  Bounds:(      21.150,      22.250, 23.35, 24.45)
-      to (      24.150,      25.250, 26.35, 27.45)
-     (      21.150,      22.250, 23.35, 24.45)  
-     (      22.150,      23.250, 24.35, 25.45)  
-     (      23.150,      24.250, 25.35, 26.45)  
-     (      24.150,      25.250, 26.35, 27.45)  
+  Bounds:(21.15,22.25, 23.35, 24.45)
+      to (24.15,25.25, 26.35, 27.45)
+     (21.15,22.25, 23.35, 24.45)  
+     (22.15,23.25, 24.35, 25.45)  
+     (23.15,24.25, 25.35, 26.45)  
+     (24.15,25.25, 26.35, 27.45)  
 -----------------------------------------------------------------------
 Test 2/6
 -----------------------------------------------------------------------
 Shapefile Type: MultiPointM   # of Shapes: 3
 
-File Bounds: (       1.150,       2.250,0,4.45)
-         to  (      24.150,      25.250,0,27.45)
+File Bounds: (1.15,2.25,0,4.45)
+         to  (24.15,25.25,0,27.45)
 
 Shape:0 (MultiPointM)  nVertices=4, nParts=0
-  Bounds:(       1.150,       2.250, 0, 4.45)
-      to (       4.150,       5.250, 0, 7.45)
-     (       1.150,       2.250, 0, 4.45)  
-     (       2.150,       3.250, 0, 5.45)  
-     (       3.150,       4.250, 0, 6.45)  
-     (       4.150,       5.250, 0, 7.45)  
+  Bounds:(1.15,2.25, 0, 4.45)
+      to (4.15,5.25, 0, 7.45)
+     (1.15,2.25, 0, 4.45)  
+     (2.15,3.25, 0, 5.45)  
+     (3.15,4.25, 0, 6.45)  
+     (4.15,5.25, 0, 7.45)  
 
 Shape:1 (MultiPointM)  nVertices=4, nParts=0
-  Bounds:(      11.150,      12.250, 0, 14.45)
-      to (      14.150,      15.250, 0, 17.45)
-     (      11.150,      12.250, 0, 14.45)  
-     (      12.150,      13.250, 0, 15.45)  
-     (      13.150,      14.250, 0, 16.45)  
-     (      14.150,      15.250, 0, 17.45)  
+  Bounds:(11.15,12.25, 0, 14.45)
+      to (14.15,15.25, 0, 17.45)
+     (11.15,12.25, 0, 14.45)  
+     (12.15,13.25, 0, 15.45)  
+     (13.15,14.25, 0, 16.45)  
+     (14.15,15.25, 0, 17.45)  
 
 Shape:2 (MultiPointM)  nVertices=4, nParts=0
-  Bounds:(      21.150,      22.250, 0, 24.45)
-      to (      24.150,      25.250, 0, 27.45)
-     (      21.150,      22.250, 0, 24.45)  
-     (      22.150,      23.250, 0, 25.45)  
-     (      23.150,      24.250, 0, 26.45)  
-     (      24.150,      25.250, 0, 27.45)  
+  Bounds:(21.15,22.25, 0, 24.45)
+      to (24.15,25.25, 0, 27.45)
+     (21.15,22.25, 0, 24.45)  
+     (22.15,23.25, 0, 25.45)  
+     (23.15,24.25, 0, 26.45)  
+     (24.15,25.25, 0, 27.45)  
 -----------------------------------------------------------------------
 Test 2/7
 -----------------------------------------------------------------------
 Shapefile Type: Arc   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,0,0)
+File Bounds: (0,0,0,0)
+         to  (100,100,0,0)
 
 Shape:0 (Arc)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 0, 0)
-      to (       2.000,       2.000, 0, 0)
-     (       1.000,       1.000, 0, 0) Ring 
-     (       2.000,       1.000, 0, 0)  
-     (       2.000,       2.000, 0, 0)  
-     (       1.000,       2.000, 0, 0)  
-     (       1.000,       1.000, 0, 0)  
+  Bounds:(1,1, 0)
+      to (2,2, 0)
+     (1,1, 0) Ring 
+     (2,1, 0)  
+     (2,2, 0)  
+     (1,2, 0)  
+     (1,1, 0)  
 
 Shape:1 (Arc)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 0, 0)
-      to (       2.000,       5.000, 0, 0)
-     (       1.000,       4.000, 0, 0) Ring 
-     (       2.000,       4.000, 0, 0)  
-     (       2.000,       5.000, 0, 0)  
-     (       1.000,       5.000, 0, 0)  
-     (       1.000,       4.000, 0, 0)  
+  Bounds:(1,4, 0)
+      to (2,5, 0)
+     (1,4, 0) Ring 
+     (2,4, 0)  
+     (2,5, 0)  
+     (1,5, 0)  
+     (1,4, 0)  
 
 Shape:2 (Arc)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 0, 0)
-      to (       2.000,       8.000, 0, 0)
-     (       1.000,       7.000, 0, 0) Ring 
-     (       2.000,       7.000, 0, 0)  
-     (       2.000,       8.000, 0, 0)  
-     (       1.000,       8.000, 0, 0)  
-     (       1.000,       7.000, 0, 0)  
+  Bounds:(1,7, 0)
+      to (2,8, 0)
+     (1,7, 0) Ring 
+     (2,7, 0)  
+     (2,8, 0)  
+     (1,8, 0)  
+     (1,7, 0)  
 
 Shape:3 (Arc)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 0, 0)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 0, 0)  
-     (     100.000,     100.000, 0, 0)  
-     (     100.000,       0.000, 0, 0)  
-     (       0.000,       0.000, 0, 0)  
-   + (      10.000,      20.000, 0, 0) Ring 
-     (      30.000,      20.000, 0, 0)  
-     (      30.000,      40.000, 0, 0)  
-     (      10.000,      40.000, 0, 0)  
-     (      10.000,      20.000, 0, 0)  
-   + (      60.000,      20.000, 0, 0) Ring 
-     (      90.000,      20.000, 0, 0)  
-     (      90.000,      40.000, 0, 0)  
-     (      60.000,      40.000, 0, 0)  
-     (      60.000,      20.000, 0, 0)  
+  Bounds:(0,0, 0)
+      to (100,100, 0)
+     (0,0, 0) Ring 
+     (0,100, 0)  
+     (100,100, 0)  
+     (100,0, 0)  
+     (0,0, 0)  
+   + (10,20, 0) Ring 
+     (30,20, 0)  
+     (30,40, 0)  
+     (10,40, 0)  
+     (10,20, 0)  
+   + (60,20, 0) Ring 
+     (90,20, 0)  
+     (90,40, 0)  
+     (60,40, 0)  
+     (60,20, 0)  
 -----------------------------------------------------------------------
 Test 2/8
 -----------------------------------------------------------------------
 Shapefile Type: ArcZ   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,27.35,28.45)
+File Bounds: (0,0,0,0)
+         to  (100,100,27.35,28.45)
 
 Shape:0 (ArcZ)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 3.35, 4.45)
-      to (       2.000,       2.000, 7.35, 8.45)
-     (       1.000,       1.000, 3.35, 4.45) Ring 
-     (       2.000,       1.000, 4.35, 5.45)  
-     (       2.000,       2.000, 5.35, 6.45)  
-     (       1.000,       2.000, 6.35, 7.45)  
-     (       1.000,       1.000, 7.35, 8.45)  
+  Bounds:(1,1, 3.35, 4.45)
+      to (2,2, 7.35, 8.45)
+     (1,1, 3.35, 4.45) Ring 
+     (2,1, 4.35, 5.45)  
+     (2,2, 5.35, 6.45)  
+     (1,2, 6.35, 7.45)  
+     (1,1, 7.35, 8.45)  
 
 Shape:1 (ArcZ)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 13.35, 14.45)
-      to (       2.000,       5.000, 17.35, 18.45)
-     (       1.000,       4.000, 13.35, 14.45) Ring 
-     (       2.000,       4.000, 14.35, 15.45)  
-     (       2.000,       5.000, 15.35, 16.45)  
-     (       1.000,       5.000, 16.35, 17.45)  
-     (       1.000,       4.000, 17.35, 18.45)  
+  Bounds:(1,4, 13.35, 14.45)
+      to (2,5, 17.35, 18.45)
+     (1,4, 13.35, 14.45) Ring 
+     (2,4, 14.35, 15.45)  
+     (2,5, 15.35, 16.45)  
+     (1,5, 16.35, 17.45)  
+     (1,4, 17.35, 18.45)  
 
 Shape:2 (ArcZ)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 23.35, 24.45)
-      to (       2.000,       8.000, 27.35, 28.45)
-     (       1.000,       7.000, 23.35, 24.45) Ring 
-     (       2.000,       7.000, 24.35, 25.45)  
-     (       2.000,       8.000, 25.35, 26.45)  
-     (       1.000,       8.000, 26.35, 27.45)  
-     (       1.000,       7.000, 27.35, 28.45)  
+  Bounds:(1,7, 23.35, 24.45)
+      to (2,8, 27.35, 28.45)
+     (1,7, 23.35, 24.45) Ring 
+     (2,7, 24.35, 25.45)  
+     (2,8, 25.35, 26.45)  
+     (1,8, 26.35, 27.45)  
+     (1,7, 27.35, 28.45)  
 
 Shape:3 (ArcZ)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 14, 28)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 1, 2)  
-     (     100.000,     100.000, 2, 4)  
-     (     100.000,       0.000, 3, 6)  
-     (       0.000,       0.000, 4, 8)  
-   + (      10.000,      20.000, 5, 10) Ring 
-     (      30.000,      20.000, 6, 12)  
-     (      30.000,      40.000, 7, 14)  
-     (      10.000,      40.000, 8, 16)  
-     (      10.000,      20.000, 9, 18)  
-   + (      60.000,      20.000, 10, 20) Ring 
-     (      90.000,      20.000, 11, 22)  
-     (      90.000,      40.000, 12, 24)  
-     (      60.000,      40.000, 13, 26)  
-     (      60.000,      20.000, 14, 28)  
+  Bounds:(0,0, 0, 0)
+      to (100,100, 14, 28)
+     (0,0, 0, 0) Ring 
+     (0,100, 1, 2)  
+     (100,100, 2, 4)  
+     (100,0, 3, 6)  
+     (0,0, 4, 8)  
+   + (10,20, 5, 10) Ring 
+     (30,20, 6, 12)  
+     (30,40, 7, 14)  
+     (10,40, 8, 16)  
+     (10,20, 9, 18)  
+   + (60,20, 10, 20) Ring 
+     (90,20, 11, 22)  
+     (90,40, 12, 24)  
+     (60,40, 13, 26)  
+     (60,20, 14, 28)  
 -----------------------------------------------------------------------
 Test 2/9
 -----------------------------------------------------------------------
 Shapefile Type: ArcM   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,0,28.45)
+File Bounds: (0,0,0,0)
+         to  (100,100,0,28.45)
 
 Shape:0 (ArcM)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 0, 4.45)
-      to (       2.000,       2.000, 0, 8.45)
-     (       1.000,       1.000, 0, 4.45) Ring 
-     (       2.000,       1.000, 0, 5.45)  
-     (       2.000,       2.000, 0, 6.45)  
-     (       1.000,       2.000, 0, 7.45)  
-     (       1.000,       1.000, 0, 8.45)  
+  Bounds:(1,1, 0, 4.45)
+      to (2,2, 0, 8.45)
+     (1,1, 0, 4.45) Ring 
+     (2,1, 0, 5.45)  
+     (2,2, 0, 6.45)  
+     (1,2, 0, 7.45)  
+     (1,1, 0, 8.45)  
 
 Shape:1 (ArcM)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 0, 14.45)
-      to (       2.000,       5.000, 0, 18.45)
-     (       1.000,       4.000, 0, 14.45) Ring 
-     (       2.000,       4.000, 0, 15.45)  
-     (       2.000,       5.000, 0, 16.45)  
-     (       1.000,       5.000, 0, 17.45)  
-     (       1.000,       4.000, 0, 18.45)  
+  Bounds:(1,4, 0, 14.45)
+      to (2,5, 0, 18.45)
+     (1,4, 0, 14.45) Ring 
+     (2,4, 0, 15.45)  
+     (2,5, 0, 16.45)  
+     (1,5, 0, 17.45)  
+     (1,4, 0, 18.45)  
 
 Shape:2 (ArcM)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 0, 24.45)
-      to (       2.000,       8.000, 0, 28.45)
-     (       1.000,       7.000, 0, 24.45) Ring 
-     (       2.000,       7.000, 0, 25.45)  
-     (       2.000,       8.000, 0, 26.45)  
-     (       1.000,       8.000, 0, 27.45)  
-     (       1.000,       7.000, 0, 28.45)  
+  Bounds:(1,7, 0, 24.45)
+      to (2,8, 0, 28.45)
+     (1,7, 0, 24.45) Ring 
+     (2,7, 0, 25.45)  
+     (2,8, 0, 26.45)  
+     (1,8, 0, 27.45)  
+     (1,7, 0, 28.45)  
 
 Shape:3 (ArcM)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 0, 28)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 0, 2)  
-     (     100.000,     100.000, 0, 4)  
-     (     100.000,       0.000, 0, 6)  
-     (       0.000,       0.000, 0, 8)  
-   + (      10.000,      20.000, 0, 10) Ring 
-     (      30.000,      20.000, 0, 12)  
-     (      30.000,      40.000, 0, 14)  
-     (      10.000,      40.000, 0, 16)  
-     (      10.000,      20.000, 0, 18)  
-   + (      60.000,      20.000, 0, 20) Ring 
-     (      90.000,      20.000, 0, 22)  
-     (      90.000,      40.000, 0, 24)  
-     (      60.000,      40.000, 0, 26)  
-     (      60.000,      20.000, 0, 28)  
+  Bounds:(0,0, 0, 0)
+      to (100,100, 0, 28)
+     (0,0, 0, 0) Ring 
+     (0,100, 0, 2)  
+     (100,100, 0, 4)  
+     (100,0, 0, 6)  
+     (0,0, 0, 8)  
+   + (10,20, 0, 10) Ring 
+     (30,20, 0, 12)  
+     (30,40, 0, 14)  
+     (10,40, 0, 16)  
+     (10,20, 0, 18)  
+   + (60,20, 0, 20) Ring 
+     (90,20, 0, 22)  
+     (90,40, 0, 24)  
+     (60,40, 0, 26)  
+     (60,20, 0, 28)  
 -----------------------------------------------------------------------
 Test 2/10
 -----------------------------------------------------------------------
 Shapefile Type: Polygon   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,0,0)
+File Bounds: (0,0,0,0)
+         to  (100,100,0,0)
 
 Shape:0 (Polygon)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 0, 0)
-      to (       2.000,       2.000, 0, 0)
-     (       1.000,       1.000, 0, 0) Ring 
-     (       2.000,       1.000, 0, 0)  
-     (       2.000,       2.000, 0, 0)  
-     (       1.000,       2.000, 0, 0)  
-     (       1.000,       1.000, 0, 0)  
+  Bounds:(1,1, 0)
+      to (2,2, 0)
+     (1,1, 0) Ring 
+     (2,1, 0)  
+     (2,2, 0)  
+     (1,2, 0)  
+     (1,1, 0)  
 
 Shape:1 (Polygon)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 0, 0)
-      to (       2.000,       5.000, 0, 0)
-     (       1.000,       4.000, 0, 0) Ring 
-     (       2.000,       4.000, 0, 0)  
-     (       2.000,       5.000, 0, 0)  
-     (       1.000,       5.000, 0, 0)  
-     (       1.000,       4.000, 0, 0)  
+  Bounds:(1,4, 0)
+      to (2,5, 0)
+     (1,4, 0) Ring 
+     (2,4, 0)  
+     (2,5, 0)  
+     (1,5, 0)  
+     (1,4, 0)  
 
 Shape:2 (Polygon)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 0, 0)
-      to (       2.000,       8.000, 0, 0)
-     (       1.000,       7.000, 0, 0) Ring 
-     (       2.000,       7.000, 0, 0)  
-     (       2.000,       8.000, 0, 0)  
-     (       1.000,       8.000, 0, 0)  
-     (       1.000,       7.000, 0, 0)  
+  Bounds:(1,7, 0)
+      to (2,8, 0)
+     (1,7, 0) Ring 
+     (2,7, 0)  
+     (2,8, 0)  
+     (1,8, 0)  
+     (1,7, 0)  
 
 Shape:3 (Polygon)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 0, 0)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 0, 0)  
-     (     100.000,     100.000, 0, 0)  
-     (     100.000,       0.000, 0, 0)  
-     (       0.000,       0.000, 0, 0)  
-   + (      10.000,      20.000, 0, 0) Ring 
-     (      30.000,      20.000, 0, 0)  
-     (      30.000,      40.000, 0, 0)  
-     (      10.000,      40.000, 0, 0)  
-     (      10.000,      20.000, 0, 0)  
-   + (      60.000,      20.000, 0, 0) Ring 
-     (      90.000,      20.000, 0, 0)  
-     (      90.000,      40.000, 0, 0)  
-     (      60.000,      40.000, 0, 0)  
-     (      60.000,      20.000, 0, 0)  
+  Bounds:(0,0, 0)
+      to (100,100, 0)
+     (0,0, 0) Ring 
+     (0,100, 0)  
+     (100,100, 0)  
+     (100,0, 0)  
+     (0,0, 0)  
+   + (10,20, 0) Ring 
+     (30,20, 0)  
+     (30,40, 0)  
+     (10,40, 0)  
+     (10,20, 0)  
+   + (60,20, 0) Ring 
+     (90,20, 0)  
+     (90,40, 0)  
+     (60,40, 0)  
+     (60,20, 0)  
 -----------------------------------------------------------------------
 Test 2/11
 -----------------------------------------------------------------------
 Shapefile Type: PolygonZ   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,27.35,28.45)
+File Bounds: (0,0,0,0)
+         to  (100,100,27.35,28.45)
 
 Shape:0 (PolygonZ)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 3.35, 4.45)
-      to (       2.000,       2.000, 7.35, 8.45)
-     (       1.000,       1.000, 3.35, 4.45) Ring 
-     (       2.000,       1.000, 4.35, 5.45)  
-     (       2.000,       2.000, 5.35, 6.45)  
-     (       1.000,       2.000, 6.35, 7.45)  
-     (       1.000,       1.000, 7.35, 8.45)  
+  Bounds:(1,1, 3.35, 4.45)
+      to (2,2, 7.35, 8.45)
+     (1,1, 3.35, 4.45) Ring 
+     (2,1, 4.35, 5.45)  
+     (2,2, 5.35, 6.45)  
+     (1,2, 6.35, 7.45)  
+     (1,1, 7.35, 8.45)  
 
 Shape:1 (PolygonZ)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 13.35, 14.45)
-      to (       2.000,       5.000, 17.35, 18.45)
-     (       1.000,       4.000, 13.35, 14.45) Ring 
-     (       2.000,       4.000, 14.35, 15.45)  
-     (       2.000,       5.000, 15.35, 16.45)  
-     (       1.000,       5.000, 16.35, 17.45)  
-     (       1.000,       4.000, 17.35, 18.45)  
+  Bounds:(1,4, 13.35, 14.45)
+      to (2,5, 17.35, 18.45)
+     (1,4, 13.35, 14.45) Ring 
+     (2,4, 14.35, 15.45)  
+     (2,5, 15.35, 16.45)  
+     (1,5, 16.35, 17.45)  
+     (1,4, 17.35, 18.45)  
 
 Shape:2 (PolygonZ)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 23.35, 24.45)
-      to (       2.000,       8.000, 27.35, 28.45)
-     (       1.000,       7.000, 23.35, 24.45) Ring 
-     (       2.000,       7.000, 24.35, 25.45)  
-     (       2.000,       8.000, 25.35, 26.45)  
-     (       1.000,       8.000, 26.35, 27.45)  
-     (       1.000,       7.000, 27.35, 28.45)  
+  Bounds:(1,7, 23.35, 24.45)
+      to (2,8, 27.35, 28.45)
+     (1,7, 23.35, 24.45) Ring 
+     (2,7, 24.35, 25.45)  
+     (2,8, 25.35, 26.45)  
+     (1,8, 26.35, 27.45)  
+     (1,7, 27.35, 28.45)  
 
 Shape:3 (PolygonZ)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 14, 28)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 1, 2)  
-     (     100.000,     100.000, 2, 4)  
-     (     100.000,       0.000, 3, 6)  
-     (       0.000,       0.000, 4, 8)  
-   + (      10.000,      20.000, 5, 10) Ring 
-     (      30.000,      20.000, 6, 12)  
-     (      30.000,      40.000, 7, 14)  
-     (      10.000,      40.000, 8, 16)  
-     (      10.000,      20.000, 9, 18)  
-   + (      60.000,      20.000, 10, 20) Ring 
-     (      90.000,      20.000, 11, 22)  
-     (      90.000,      40.000, 12, 24)  
-     (      60.000,      40.000, 13, 26)  
-     (      60.000,      20.000, 14, 28)  
+  Bounds:(0,0, 0, 0)
+      to (100,100, 14, 28)
+     (0,0, 0, 0) Ring 
+     (0,100, 1, 2)  
+     (100,100, 2, 4)  
+     (100,0, 3, 6)  
+     (0,0, 4, 8)  
+   + (10,20, 5, 10) Ring 
+     (30,20, 6, 12)  
+     (30,40, 7, 14)  
+     (10,40, 8, 16)  
+     (10,20, 9, 18)  
+   + (60,20, 10, 20) Ring 
+     (90,20, 11, 22)  
+     (90,40, 12, 24)  
+     (60,40, 13, 26)  
+     (60,20, 14, 28)  
 -----------------------------------------------------------------------
 Test 2/12
 -----------------------------------------------------------------------
 Shapefile Type: PolygonM   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,0,28.45)
+File Bounds: (0,0,0,0)
+         to  (100,100,0,28.45)
 
 Shape:0 (PolygonM)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 0, 4.45)
-      to (       2.000,       2.000, 0, 8.45)
-     (       1.000,       1.000, 0, 4.45) Ring 
-     (       2.000,       1.000, 0, 5.45)  
-     (       2.000,       2.000, 0, 6.45)  
-     (       1.000,       2.000, 0, 7.45)  
-     (       1.000,       1.000, 0, 8.45)  
+  Bounds:(1,1, 0, 4.45)
+      to (2,2, 0, 8.45)
+     (1,1, 0, 4.45) Ring 
+     (2,1, 0, 5.45)  
+     (2,2, 0, 6.45)  
+     (1,2, 0, 7.45)  
+     (1,1, 0, 8.45)  
 
 Shape:1 (PolygonM)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 0, 14.45)
-      to (       2.000,       5.000, 0, 18.45)
-     (       1.000,       4.000, 0, 14.45) Ring 
-     (       2.000,       4.000, 0, 15.45)  
-     (       2.000,       5.000, 0, 16.45)  
-     (       1.000,       5.000, 0, 17.45)  
-     (       1.000,       4.000, 0, 18.45)  
+  Bounds:(1,4, 0, 14.45)
+      to (2,5, 0, 18.45)
+     (1,4, 0, 14.45) Ring 
+     (2,4, 0, 15.45)  
+     (2,5, 0, 16.45)  
+     (1,5, 0, 17.45)  
+     (1,4, 0, 18.45)  
 
 Shape:2 (PolygonM)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 0, 24.45)
-      to (       2.000,       8.000, 0, 28.45)
-     (       1.000,       7.000, 0, 24.45) Ring 
-     (       2.000,       7.000, 0, 25.45)  
-     (       2.000,       8.000, 0, 26.45)  
-     (       1.000,       8.000, 0, 27.45)  
-     (       1.000,       7.000, 0, 28.45)  
+  Bounds:(1,7, 0, 24.45)
+      to (2,8, 0, 28.45)
+     (1,7, 0, 24.45) Ring 
+     (2,7, 0, 25.45)  
+     (2,8, 0, 26.45)  
+     (1,8, 0, 27.45)  
+     (1,7, 0, 28.45)  
 
 Shape:3 (PolygonM)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 0, 28)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 0, 2)  
-     (     100.000,     100.000, 0, 4)  
-     (     100.000,       0.000, 0, 6)  
-     (       0.000,       0.000, 0, 8)  
-   + (      10.000,      20.000, 0, 10) Ring 
-     (      30.000,      20.000, 0, 12)  
-     (      30.000,      40.000, 0, 14)  
-     (      10.000,      40.000, 0, 16)  
-     (      10.000,      20.000, 0, 18)  
-   + (      60.000,      20.000, 0, 20) Ring 
-     (      90.000,      20.000, 0, 22)  
-     (      90.000,      40.000, 0, 24)  
-     (      60.000,      40.000, 0, 26)  
-     (      60.000,      20.000, 0, 28)  
+  Bounds:(0,0, 0, 0)
+      to (100,100, 0, 28)
+     (0,0, 0, 0) Ring 
+     (0,100, 0, 2)  
+     (100,100, 0, 4)  
+     (100,0, 0, 6)  
+     (0,0, 0, 8)  
+   + (10,20, 0, 10) Ring 
+     (30,20, 0, 12)  
+     (30,40, 0, 14)  
+     (10,40, 0, 16)  
+     (10,20, 0, 18)  
+   + (60,20, 0, 20) Ring 
+     (90,20, 0, 22)  
+     (90,40, 0, 24)  
+     (60,40, 0, 26)  
+     (60,20, 0, 28)  
 -----------------------------------------------------------------------
 Test 2/13
 -----------------------------------------------------------------------
 Shapefile Type: MultiPatch   # of Shapes: 4
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     100.000,     100.000,27.35,28.45)
+File Bounds: (0,0,0,0)
+         to  (100,100,27.35,28.45)
 
 Shape:0 (MultiPatch)  nVertices=5, nParts=1
-  Bounds:(       1.000,       1.000, 3.35, 0)
-      to (       2.000,       2.000, 7.35, 0)
-     (       1.000,       1.000, 3.35, 0) Ring 
-     (       2.000,       1.000, 4.35, 0)  
-     (       2.000,       2.000, 5.35, 0)  
-     (       1.000,       2.000, 6.35, 0)  
-     (       1.000,       1.000, 7.35, 0)  
+  Bounds:(1,1, 3.35)
+      to (2,2, 7.35)
+     (1,1, 3.35) Ring 
+     (2,1, 4.35)  
+     (2,2, 5.35)  
+     (1,2, 6.35)  
+     (1,1, 7.35)  
 
 Shape:1 (MultiPatch)  nVertices=5, nParts=1
-  Bounds:(       1.000,       4.000, 13.35, 0)
-      to (       2.000,       5.000, 17.35, 0)
-     (       1.000,       4.000, 13.35, 0) Ring 
-     (       2.000,       4.000, 14.35, 0)  
-     (       2.000,       5.000, 15.35, 0)  
-     (       1.000,       5.000, 16.35, 0)  
-     (       1.000,       4.000, 17.35, 0)  
+  Bounds:(1,4, 13.35)
+      to (2,5, 17.35)
+     (1,4, 13.35) Ring 
+     (2,4, 14.35)  
+     (2,5, 15.35)  
+     (1,5, 16.35)  
+     (1,4, 17.35)  
 
 Shape:2 (MultiPatch)  nVertices=5, nParts=1
-  Bounds:(       1.000,       7.000, 23.35, 0)
-      to (       2.000,       8.000, 27.35, 0)
-     (       1.000,       7.000, 23.35, 0) Ring 
-     (       2.000,       7.000, 24.35, 0)  
-     (       2.000,       8.000, 25.35, 0)  
-     (       1.000,       8.000, 26.35, 0)  
-     (       1.000,       7.000, 27.35, 0)  
+  Bounds:(1,7, 23.35)
+      to (2,8, 27.35)
+     (1,7, 23.35) Ring 
+     (2,7, 24.35)  
+     (2,8, 25.35)  
+     (1,8, 26.35)  
+     (1,7, 27.35)  
 
 Shape:3 (MultiPatch)  nVertices=15, nParts=3
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 14, 0)
-     (       0.000,       0.000, 0, 0) Ring 
-     (       0.000,     100.000, 1, 0)  
-     (     100.000,     100.000, 2, 0)  
-     (     100.000,       0.000, 3, 0)  
-     (       0.000,       0.000, 4, 0)  
-   + (      10.000,      20.000, 5, 0) InnerRing 
-     (      30.000,      20.000, 6, 0)  
-     (      30.000,      40.000, 7, 0)  
-     (      10.000,      40.000, 8, 0)  
-     (      10.000,      20.000, 9, 0)  
-   + (      60.000,      20.000, 10, 0) InnerRing 
-     (      90.000,      20.000, 11, 0)  
-     (      90.000,      40.000, 12, 0)  
-     (      60.000,      40.000, 13, 0)  
-     (      60.000,      20.000, 14, 0)  
+  Bounds:(0,0, 0)
+      to (100,100, 14)
+     (0,0, 0) Ring 
+     (0,100, 1)  
+     (100,100, 2)  
+     (100,0, 3)  
+     (0,0, 4)  
+   + (10,20, 5) InnerRing 
+     (30,20, 6)  
+     (30,40, 7)  
+     (10,40, 8)  
+     (10,20, 9)  
+   + (60,20, 10) InnerRing 
+     (90,20, 11)  
+     (90,40, 12)  
+     (60,40, 13)  
+     (60,20, 14)  
diff --git a/stream3.out b/stream3.out
index b668233..1ab8af4 100644
--- a/stream3.out
+++ b/stream3.out
@@ -1,36 +1,36 @@
 Shapefile Type: Polygon   # of Shapes: 3
 
-File Bounds: (       0.000,       0.000,0,0)
-         to  (     180.000,     170.000,0,0)
+File Bounds: (0,0,0,0)
+         to  (180,170,0,0)
 
 Shape:0 (Polygon)  nVertices=9, nParts=2
-  Bounds:(       0.000,       0.000, 0, 0)
-      to (     100.000,     100.000, 0, 0)
-     (       0.000,       0.000, 0, 0) Ring 
-     (     100.000,       0.000, 0, 0)  
-     (     100.000,     100.000, 0, 0)  
-     (       0.000,     100.000, 0, 0)  
-     (       0.000,       0.000, 0, 0)  
-   + (      20.000,      20.000, 0, 0) Ring 
-     (      20.000,      30.000, 0, 0)  
-     (      30.000,      30.000, 0, 0)  
-     (      20.000,      20.000, 0, 0)  
+  Bounds:(0,0, 0)
+      to (100,100, 0)
+     (0,0, 0) Ring 
+     (100,0, 0)  
+     (100,100, 0)  
+     (0,100, 0)  
+     (0,0, 0)  
+   + (20,20, 0) Ring 
+     (20,30, 0)  
+     (30,30, 0)  
+     (20,20, 0)  
 
 Shape:1 (Polygon)  nVertices=4, nParts=1
-  Bounds:(     150.000,     150.000, 0, 0)
-      to (     180.000,     170.000, 0, 0)
-     (     150.000,     150.000, 0, 0) Ring 
-     (     160.000,     150.000, 0, 0)  
-     (     180.000,     170.000, 0, 0)  
-     (     150.000,     150.000, 0, 0)  
+  Bounds:(150,150, 0)
+      to (180,170, 0)
+     (150,150, 0) Ring 
+     (160,150, 0)  
+     (180,170, 0)  
+     (150,150, 0)  
 
 Shape:2 (Polygon)  nVertices=4, nParts=1
-  Bounds:(     150.000,     150.000, 0, 0)
-      to (     180.000,     170.000, 0, 0)
-     (     150.000,     150.000, 0, 0) Ring 
-     (     160.000,     150.000, 0, 0)  
-     (     180.000,     170.000, 0, 0)  
-     (     150.000,     150.000, 0, 0)  
+  Bounds:(150,150, 0)
+      to (180,170, 0)
+     (150,150, 0) Ring 
+     (160,150, 0)  
+     (180,170, 0)  
+     (150,150, 0)  
 Descriptio                     TestInt       TestDouble 
 Square with triangle missing        1           2.50000 
 Smaller triangle                  100        1000.25000 
diff --git a/web/.cvsignore b/web/.cvsignore
new file mode 100644
index 0000000..d6ffe8d
--- /dev/null
+++ b/web/.cvsignore
@@ -0,0 +1,2 @@
+robots.txt
+dl
diff --git a/web/codepage.html b/web/codepage.html
new file mode 100644
index 0000000..23a9cfb
--- /dev/null
+++ b/web/codepage.html
@@ -0,0 +1,403 @@
+
+This table is derived from:<p>
+
+<a href="http://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTM">http://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTM</a><p>
+
+
+<table border="1" width="100%">
+  <tbody><tr>
+    <th colspan="2" align="left" bgcolor="#c0c0c0">ID</th>
+    <th align="left" bgcolor="#c0c0c0">Codepage</th>
+    <th align="left" bgcolor="#c0c0c0">Description</th>
+  </tr>
+  <tr>
+    <td>1</td>
+    <td>0x01</td>
+    <td>437</td>
+    <td>US MS-DOS</td>
+  </tr>
+  <tr>
+    <td>2</td>
+    <td>0x02</td>
+    <td>850</td>
+    <td>International MS-DOS</td>
+  </tr>
+  <tr>
+    <td>3</td>
+    <td>0x03</td>
+    <td>1252</td>
+    <td>Windows ANSI Latin I</td>
+  </tr>
+  <tr>
+    <td>4</td>
+    <td>0x04</td>
+    <td>10000</td>
+    <td>Standard Macintosh</td>
+  </tr>
+	<tr>
+    <td>8</td>
+    <td>0x08</td>
+    <td>865</td>
+    <td>Danish OEM</td>
+  </tr>
+	<tr>
+    <td>9</td>
+    <td>0x09</td>
+    <td>437</td>
+    <td>Dutch OEM</td>
+  </tr>
+	<tr>
+    <td>10</td>
+    <td>0x0A</td>
+    <td>850</td>
+    <td>Dutch OEM*</td>
+  </tr>
+	<tr>
+    <td>11</td>
+    <td>0x0B</td>
+    <td>437</td>
+    <td>Finnish OEM</td>
+  </tr>
+	<tr>
+    <td>13</td>
+    <td>0x0D</td>
+    <td>437</td>
+    <td>French OEM</td>
+  </tr>
+	<tr>
+    <td>14</td>
+    <td>0x0E</td>
+    <td>850</td>
+    <td>French OEM*</td>
+  </tr>
+	<tr>
+    <td>15</td>
+    <td>0x0F</td>
+    <td>437</td>
+    <td>German OEM</td>
+  </tr>
+	<tr>
+    <td>16</td>
+    <td>0x10</td>
+    <td>850</td>
+    <td>German OEM*</td>
+  </tr>
+	<tr>
+    <td>17</td>
+    <td>0x11</td>
+    <td>437</td>
+    <td>Italian OEM</td>
+  </tr>
+	<tr>
+    <td>18</td>
+    <td>0x12</td>
+    <td>850</td>
+    <td>Italian OEM*</td>
+  </tr>
+	<tr>
+    <td>19</td>
+    <td>0x13</td>
+    <td>932</td>
+    <td>Japanese Shift-JIS</td>
+  </tr>
+	<tr>
+    <td>20</td>
+    <td>0x14</td>
+    <td>850</td>
+    <td>Spanish OEM*</td>
+  </tr>
+	<tr>
+    <td>21</td>
+    <td>0x15</td>
+    <td>437</td>
+    <td>Swedish OEM</td>
+  </tr>
+	<tr>
+    <td>22</td>
+    <td>0x16</td>
+    <td>850</td>
+    <td>Swedish OEM*</td>
+  </tr>
+	<tr>
+    <td>23</td>
+    <td>0x17</td>
+    <td>865</td>
+    <td>Norwegian OEM</td>
+  </tr>
+	<tr>
+    <td>24</td>
+    <td>0x18</td>
+    <td>437</td>
+    <td>Spanish OEM</td>
+  </tr>
+	<tr>
+    <td>25</td>
+    <td>0x19</td>
+    <td>437</td>
+    <td>English OEM (Great Britain)</td>
+  </tr>
+	<tr>
+    <td>26</td>
+    <td>0x1A</td>
+    <td>850</td>
+    <td>English OEM (Great Britain)*</td>
+  </tr>
+	<tr>
+    <td>27</td>
+    <td>0x1B</td>
+    <td>437</td>
+    <td>English OEM (US)</td>
+  </tr>
+	<tr>
+    <td>28</td>
+    <td>0x1C</td>
+    <td>863</td>
+    <td>French OEM (Canada)</td>
+  </tr>
+	<tr>
+    <td>29</td>
+    <td>0x1D</td>
+    <td>850</td>
+    <td>French OEM*</td>
+  </tr>
+	<tr>
+    <td>31</td>
+    <td>0x1F</td>
+    <td>852</td>
+    <td>Czech OEM</td>
+  </tr>
+	<tr>
+    <td>34</td>
+    <td>0x22</td>
+    <td>852</td>
+    <td>Hungarian OEM</td>
+  </tr>
+	<tr>
+    <td>35</td>
+    <td>0x23</td>
+    <td>852</td>
+    <td>Polish OEM</td>
+  </tr>
+	<tr>
+    <td>36</td>
+    <td>0x24</td>
+    <td>860</td>
+    <td>Portuguese OEM</td>
+  </tr>
+	<tr>
+    <td>37</td>
+    <td>0x25</td>
+    <td>850</td>
+    <td>Portuguese OEM*</td>
+  </tr>
+  <tr>
+    <td>38</td>
+    <td>0x26</td>
+    <td>866</td>
+    <td>Russian OEM</td>
+  </tr>
+  <tr>
+    <td>55</td>
+    <td>0x37</td>
+    <td>850</td>
+    <td>English OEM (US)*</td>
+  </tr>
+	<tr>
+    <td>64</td>
+    <td>0x40</td>
+    <td>852</td>
+    <td>Romanian OEM</td>
+  </tr>
+	<tr>
+    <td>77</td>
+    <td>0x4D</td>
+    <td>936</td>
+    <td>Chinese GBK (PRC)</td>
+  </tr>
+	<tr>
+    <td>78</td>
+    <td>0x4E</td>
+    <td>949</td>
+    <td>Korean (ANSI/OEM)</td>
+  </tr>
+	<tr>
+    <td>79</td>
+    <td>0x4F</td>
+    <td>950</td>
+    <td>Chinese Big5 (Taiwan)</td>
+  </tr>
+	<tr>
+    <td>80</td>
+    <td>0x50</td>
+    <td>874</td>
+    <td>Thai (ANSI/OEM)</td>
+  </tr>
+	<tr>
+    <td>87</td>
+    <td>0x57</td>
+    <td>Current ANSI CP</td>
+    <td>ANSI</td>
+  </tr>
+  <tr>
+    <td>88</td>
+    <td>0x58</td>
+    <td>1252</td>
+    <td>Western European ANSI</td>
+  </tr>
+	<tr>
+    <td>89</td>
+    <td>0x59</td>
+    <td>1252</td>
+    <td>Spanish ANSI</td>
+  </tr>
+  <tr>
+    <td>100</td>
+    <td>0x64</td>
+    <td>852</td>
+    <td>Eastern European MS-DOS</td>
+  </tr>
+  <tr>
+    <td>101</td>
+    <td>0x65</td>
+    <td>866</td>
+    <td>Russian MS-DOS</td>
+  </tr>
+  <tr>
+    <td>102</td>
+    <td>0x66</td>
+    <td>865</td>
+    <td>Nordic MS-DOS</td>
+  </tr>
+  <tr>
+    <td>103</td>
+    <td>0x67</td>
+    <td>861</td>
+    <td>Icelandic MS-DOS</td>
+  </tr>
+  <tr>
+    <td>104</td>
+    <td>0x68</td>
+    <td>895</td>
+    <td>Kamenicky (Czech) MS-DOS</td>
+  </tr>
+  <tr>
+    <td>105</td>
+    <td>0x69</td>
+    <td>620</td>
+    <td>Mazovia (Polish) MS-DOS</td>
+  </tr>
+  <tr>
+    <td>106</td>
+    <td>0x6A</td>
+    <td>737</td>
+    <td>Greek MS-DOS (437G)</td>
+  </tr>
+  <tr>
+    <td>107</td>
+    <td>0x6B</td>
+    <td>857</td>
+    <td>Turkish MS-DOS</td>
+  </tr>
+	<tr>
+    <td>108</td>
+    <td>0x6C</td>
+    <td>863</td>
+    <td>French-Canadian MS-DOS</td>
+  </tr>
+	<tr>
+    <td>120</td>
+    <td>0x78</td>
+    <td>950</td>
+    <td>Taiwan Big 5</td>
+  </tr>
+	<tr>
+    <td>121</td>
+    <td>0x79</td>
+    <td>949</td>
+    <td>Hangul (Wansung)</td>
+  </tr>
+	<tr>
+    <td>122</td>
+    <td>0x7A</td>
+    <td>936</td>
+    <td>PRC GBK</td>
+  </tr>
+	<tr>
+    <td>123</td>
+    <td>0x7B</td>
+    <td>932</td>
+    <td>Japanese Shift-JIS</td>
+  </tr>
+	<tr>
+    <td>124</td>
+    <td>0x7C</td>
+    <td>874</td>
+    <td>Thai Windows/MS–DOS</td>
+  </tr>
+	<tr>
+    <td>134</td>
+    <td>0x86</td>
+    <td>737</td>
+    <td>Greek OEM</td>
+  </tr>
+	<tr>
+    <td>135</td>
+    <td>0x87</td>
+    <td>852</td>
+    <td>Slovenian OEM</td>
+  </tr>
+	<tr>
+    <td>136</td>
+    <td>0x88</td>
+    <td>857</td>
+    <td>Turkish OEM</td>
+  </tr>
+  <tr>
+    <td>150</td>
+    <td>0x96</td>
+    <td>10007</td>
+    <td>Russian Macintosh</td>
+  </tr>
+  <tr>
+    <td>151</td>
+    <td>0x97</td>
+    <td>10029</td>
+    <td>Eastern European Macintosh</td>
+  </tr>
+  <tr>
+    <td>152</td>
+    <td>0x98</td>
+    <td>10006</td>
+    <td>Greek Macintosh</td>
+  </tr>
+  <tr>
+    <td>200</td>
+    <td>0xC8</td>
+    <td>1250</td>
+    <td>Eastern European Windows</td>
+  </tr>
+  <tr>
+    <td>201</td>
+    <td>0xC9</td>
+    <td>1251</td>
+    <td>Russian Windows</td>
+  </tr>
+  <tr>
+    <td>202</td>
+    <td>0xCA</td>
+    <td>1254</td>
+    <td>Turkish Windows</td>
+  </tr>
+  <tr>
+    <td>203</td>
+    <td>0xCB</td>
+    <td>1253</td>
+    <td>Greek Windows</td>
+  </tr>
+  <tr>
+    <td>204</td>
+    <td>0xCC</td>
+    <td>1257</td>
+    <td>Baltic Windows</td>
+  </tr>
+</tbody></table>
diff --git a/dbf_api.html b/web/dbf_api.html
similarity index 95%
rename from dbf_api.html
rename to web/dbf_api.html
index b0fa373..f7a311b 100644
--- a/dbf_api.html
+++ b/web/dbf_api.html
@@ -381,6 +381,34 @@ void DBFClose( DBFHandle hDBF );
 
 <!-------------------------------------------------------------------------->
 
+<h2>DBFIsRecordDeleted()</h2>
+
+<pre>
+int DBFIsRecordDeleted( DBFHandle hDBF, int iShape );
+
+  hDBF:		The access handle for the file to be checked.
+  iShape:       The record index to check.
+</pre>
+
+  Returns TRUE (non-zero) if the record is marked for deletion, otherwise
+  it returns FALSE.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFMarkRecordDeleted()</h2>
+
+<pre>
+int DBFMarkRecordDeleted( DBFHandle hDBF, int iShape, int bIsDeleted );
+
+  hDBF:		The access handle for the file.
+  iShape:       The record index to update.
+  bIsDeleted:   TRUE to mark record deleted, or FALSE to undelete it.
+</pre>
+
+  Returns TRUE on success, or FALSE on error.<p>
+
+<!-------------------------------------------------------------------------->
+
 <h2>DBFGetNativeFieldType()</h2>
 
 <pre>
diff --git a/web/index.html b/web/index.html
new file mode 100644
index 0000000..2015283
--- /dev/null
+++ b/web/index.html
@@ -0,0 +1,235 @@
+<html>
+<head>
+<title>Shapefile C Library V1.2</title>
+<link href="http://www.maptools.org/maptools.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h1>Shapefile C Library V1.2</h1>
+
+<h2>Purpose</h2>
+
+The Shapefile C Library provides the ability to write simple C programs
+for reading, writing and updating (to a limited extent) ESRI Shapefiles,
+and the associated attribute file (.dbf).<p>
+
+<h2>Supporting Information</h2>
+
+<ul>
+<li> <a href="shp_api.html">Shapefile API Docs</a>
+<li> <a href="dbf_api.html">DBF/xBase API Docs</a>
+<li> <a href="shapelib-tools.html">Shapefile Tools Docs</a>
+<li> <a href="release.html">Release Notes</a>
+<li> <a href="manifest.html">Shapelib File Manifest</a>
+<li> <a href="license.html">Shapelib Licensing Terms</a>
+</ul>
+
+<h2>What is a Shapefile?</h2>
+
+If you don't know, you probably don't need this library.  The Shapefile
+format is a working and interchange format promulagated by 
+<a href="http://www.esri.com/">ESRI</a> for simple vector data with attributes.
+<p>
+
+An excellent <a href="dl/shapefile.pdf">white paper</a> on the shapefile format 
+is available from ESRI,
+but it is .pdf format, so you will need Adobe Acrobat to browse it.<p>
+
+The file format actually consists of three files.<p>
+
+<pre>
+XXX.shp - holds the actual vertices.
+XXX.shx - hold index data pointing to the structures in the .shp file.
+XXX.dbf - holds the attributes in xBase (dBase) format.  
+</pre>
+
+<h2>Download</h2>
+
+Source code, and some other odds and ends can be downloaded from
+<a href="http://download.osgeo.org/shapelib">http://download.osgeo.org/shapelib</a> or <a href="http://shapelib.maptools.org/dl">http://shapelib.maptools.org/dl</a>.<p>
+
+Shapelib is available for anonymous CVS access:
+
+<pre>
+  cvs -d :pserver:cvsanon at cvs.maptools.org:/cvs/maptools/cvsroot login
+  Password: (hit enter)
+  cvs -d :pserver:cvsanon at cvs.maptools.org:/cvs/maptools/cvsroot co shapelib
+</pre>
+
+<h2>Bugs, Maintainance and Support</h2>
+
+This library is maintained by <a href="http://pobox.com/~warmerdam">Frank 
+Warmerdam</a>.  Please send me bug reports, patches and suggestions for the 
+library via the <a href="http://bugzilla.maptools.org/enter_bug.cgi?product=Shapelib">maptools.org Bugzilla</a>.  Shapelib bugs can also be
+<a href="http://bugzilla.maptools.org/query.cgi?product=Shapelib">queried</a>.
+<p>
+
+Shapelib is hosted at 
+<a href="http://shapelib.maptools.org">shapelib.maptools.org</a>.   A mailing
+list for discussion of how to use shapelib, and announcing new releases 
+<a href="http://lists.maptools.org/mailman/listinfo/shapelib/">is 
+available</a>.  To only find out about new releases of Shapelib select the 
+"<i>Subscribe to new releases</i>" option from the link at 
+<a href="http://freshmeat.net/projects/shapelib/">Freshmeat</a>.<p>
+
+<h2>Credits</h2>
+
+I didn't start this section anywhere near soon enough, so alot of earlier
+contributors to Shapelib are lost in pre-history.
+
+<ul>
+<li> Bill Miller (NY-DOT) for shputils.c
+<li> Carl Anderson for the contents of the contrib directory, and 
+the "tuple" additions to dbfopen.c.
+<li> Andrea Giacomelli for patches for dbfopen.c.
+<li> Doug Matthews for portability improvements.
+<li> Jan-Oliver Wagner for convincing me to make it available under LGPL,
+shared library support, and various other patches.
+<li> Dennis Christopher (of Avenza) for testing and bug fixes.
+<li> Miko Syrjä (of 3D-system Oy) for a record size bug fix.
+<li> Steven Lime and Curtis Hill for help with NULL shapes.
+<li> Jim Matthews for support of NULL attributes in dbf files.
+<li> <a href="http://www.pcigeomatics.com/">PCI Geomatics</a> who let me
+release a modified version of their shapefile code in the beginning and
+who hosted shapelib for years.
+</ul>
+
+<h2>In Memorium</h2>
+
+I would like to dedicate Shapelib to the memory of Sol Katz.  While I never
+met him in person, his generous contributions to the GIS community took 
+many forms, including free distribution of a variety of GIS translators
+with source.  The fact that he used this Shapelib in some of his utilities, 
+and thanked me was a great encouragement to me.  I hope I can do his memory 
+honour by trying to contribute in a similar fashion.<p>
+
+<h2>Portability</h2>
+
+The Shapefile C Library should port easily to 32bit systems with ANSI C
+compilers.  It should work on 64 bit architectures (such as the DEC AXP).<p>
+
+Care should also be taken to pass the binary access flag into SHPOpen()
+and DBFOpen() when operating on systems with special text file translation
+such as MSDOS.<p>
+
+The shputils.c module is contributed, and may not take the same approach
+to portability as the rest of the package.<p>
+
+On Linux, and most unix systems it should be possible to build and 
+install shapefile support as a shared library using the "lib" and "lib_install"
+targets of the Makefile.  Note that this Makefile doesn't use autoconf
+mechanisms and will generally require some hand tailoring for your environment.
+
+<h2>Limitations</h2>
+
+<ul>
+
+<li> You can't modify the vertices of existing structures (though you 
+   can update the attributes of existing structures, and create new 
+   structures).<p>
+
+<li> Not written in such a way as to be particularly fast.  This is 
+particularly true of the 1.2 API.  For applications more concerned with
+speed it may be worth using the V1.1 API.<p>
+
+<li> Doesn't set the last access time properly in the .dbf files.<p>
+
+<li> There is no way to synchronize information to the file except to close it.
+<p>
+
+<li> Poor error checking and reporting.<p>
+
+<li> Not professionally supported (well it can be, if you want to pay).<p>
+
+<li> Some aspects of xBase files not supported, though I believe they are
+not used by ESRI.<p>
+
+<li> The application must keep the .dbf file in sync with the .shp/.shx
+files through appropriate use of the DBF and SHP APIs.<p>
+
+<li> No support for the undocumented .sbn/.sbx spatial index files.<p>
+
+</ul>
+
+<h2>Other Shapefile Resources</h2>
+
+<ul>
+<li> <a href="dl/shapefile.pdf">Shapefile Format Specifications (pdf)</a><p>
+
+<li> <a href="http://www.clicketyclick.dk/databases/xbase/format/">Xbase (.dbf) File Format Description</a>. <p>
+
+<li> <a href="codepage.html">Language ID / Code Page mappings</a><p>
+
+<li> Shapelib is used within the multiformat 
+<a href="http://ogr.maptools.org/">OGR</a> library.  If you are looking for a 
+high level C++ library with support for many geospatial vector formats you
+might want to check it out.<p>
+
+<li> Ari Jolma has produced an initial <b>perl</b> binding on top of shapelib, 
+which can be found at CPAN as Geo::ShapeFile under the 
+<a href="http://www.cpan.org/modules/by-module/Geo/">Geo</a> module.
+<p>
+
+<li> Bernhard Herzog has produced <b>python</b> bindings for Shapelib with 
+SWIG, available at <a href="http://ftp.intevation.de/users/bh/pyshapelib/">http://ftp.intevation.de/users/bh/pyshapelib</a>.  A new version not using swig is 
+available as <a href="http://wald.intevation.org/plugins/scmsvn/viewcvs.php/trunk/thuban/libraries/pyshapelib/?root=thuban">part of Thuban</a>.<p>
+
+<li> <a href="http://www.triplexware.huckfinn.de/shpapi.html">Delphi</a>
+bindings for Shapelib courtesy of Alexander Weidauer.<p>
+
+<li> Miguel Filgueiras has implemented 
+<a href="http://www.ncc.up.pt/gpsmanshp/">Tcl</a> bindings for Shapelib
+as part of <a href="http://www.ncc.up.pt/gpsman/">GPSMan</a>.<p>
+
+<li> David Gancarz has implemented a Microsoft
+<a href="dl/contrib/DotNetArchive.zip">.NET wrapper</a> for
+Shapelib.   An example of using shapelib with VB6 is also icluded in the .NET wrapper project file.<p>
+
+<li> Andrey Hristov (php at hristov dot com) has developed a PHP extension 
+based on Shapelib.  It can be found in CVS at http://cvs.php.net/pecl/shp.<p>
+
+<li> Toyoda Eizi has developed Ruby bindings found at
+<a href="http://sourceforge.net/projects/ruby-shapelib">http://sourceforge.net/projects/ruby-shapelib</a>.<p>
+
+<li> Davide Cesari has developed FORTRAN bindings that can be found at
+<a href"http://www.webalice.it/o.drofa/davide/shapelib-fortran/">
+http://www.webalice.it/o.drofa/davide/shapelib-fortran</a>.
+
+<li> Jan-Oliver Wagner has implemented a commandline program
+(<b>gen2shp</b>) for producing shapefiles from Arc/Info Generate format ASCII
+files.  He maintains a <a href="http://intevation.de/~jan/gen2shp">web page</a> for his work. <p>
+
+<li> Tom Russo has implemented a shpcs2cs program, which reprojects shapefiles
+using arguments similar to the PROJ.4 cs2cs program including datum conversion.
+Use as an alternate to the contrib/shpproj which doesn't do datums.  It is 
+available at the bottom of Tom's <a href="http://www.swcp.com/~russo/shape_web/">Xastir Shapefile Resources</a> page. <p>
+
+<li> 
+Andrew Williamson's 
+<a href="http://www.geocities.com/SiliconValley/Haven/2295/useful.html">Useful
+Scripts and Stuff</a> page for ArcView, which includes ShapeChecker.<p>
+
+<li> The University of Bonn <a href="http://katla.giub.uni-bonn.de/sfjava/">
+sf4java</a> project apparently includes Java classes for reading Shapefiles.<p>
+
+<li> The <a href="http://gis.esri.com/arcscripts/details.cfm?CFGRIDKEY=628102085">ShapeIO2</a> Visual Basic libraries may be of interest to those wanting
+VB access to Shapefiles.  Also available <a href="http://shapelib.maptools.org/dl/contrib/ShapeIO2.zip">locally</a>.<p>
+
+<li> The <a href="http://arcscripts.esri.com/details.asp?dbid=11810">ShapeFile Read/Write OCX</a> is another option for Visual Basic programmers.<p>
+
+<li> <a href="http://www.casa.ucl.ac.uk/sanjay/software_isovistanalyst.htm">Isovist Analyst</a> is a sort-of-free isovist generating extension for 
+ArcView using shapelib.<p>
+
+<li> <a href="http://www.obviously.com/gis/shpdiff/">shpdiff</a> utility 
+by Bryce Nesbitt.<p>
+
+<li> <a href="http://www.aequometer.de/">Aequometer</a>: a program for 
+MS Excel to calculate the area of polygons and export as shapefiles.<p>
+
+</ul>
+
+</body>
+</html>
+
+
+
diff --git a/web/license.html b/web/license.html
new file mode 100644
index 0000000..8580972
--- /dev/null
+++ b/web/license.html
@@ -0,0 +1,78 @@
+<html>
+<head>
+<title>Shapelib License</title>
+<link href="http://www.maptools.org/maptools.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h1>License</h1>
+
+The source for the Shapefile C Library is (c) 1998 Frank Warmerdam, 
+and released under the following conditions.  The intent is that anyone
+can do anything with the code, but that I do not assume any liability, nor
+express any warranty for this code.  <p>
+
+As of Shapelib 1.2.6 the core portions of the library are made available
+under two possible licenses.  The licensee can choose to use the code
+under either the Library GNU Public License (LGPL) described in 
+LICENSE.LGPL or under the following MIT style license.  Any files in
+the Shapelib distribution without explicit copyright license terms
+(such as this documentation, the Makefile and so forth) should be
+considered to have the following licensing terms.  Some auxilary portions
+of Shapelib, notably some of the components in the contrib directory
+come under slightly different license restrictions.  Check the source
+files that you are actually using for conditions.<p>
+
+<h3>Default License Terms</h3>
+
+<quote>
+Copyright (c) 1999, Frank Warmerdam<p>
+
+This software is available under the following "MIT Style" license,
+or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+option is discussed in more detail in shapelib.html.<p>
+ 
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:<p>
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.<p>
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.<p>
+</quote>
+
+<h3>Shapelib Modifications</h3>
+
+I am pleased to receive bug fixes, and improvements for Shapelib.  Unless
+the submissions indicate otherwise I will assume that changes submitted to
+me remain under the the above "dual license" terms.  If changes are made
+to the library with the intention that those changes should be protected by
+the LGPL then I should be informed upon submission.  Note that I will not
+generally incorporate changes into the core of Shapelib that are protected 
+under the LGPL as this would effectively limit the whole file and 
+distribution to LGPL terms.<p>
+
+<h3>Opting for LGPL</h3>
+
+For licensee's opting to use Shapelib under LGPL as opposed to the MIT
+Style license above, and wishing to redistribute the software based on 
+Shapelib, I would ask that all "dual license" modules be updated to
+indicate that only the LGPL (and not the MIT Style license) applies.  This
+action represents opting for the LGPL, and thereafter LGPL terms apply to
+any redistribution and modification of the affected modules.<p>
+
+</body>
+</html>
+
+
+
diff --git a/web/manifest.html b/web/manifest.html
new file mode 100644
index 0000000..27aeb0f
--- /dev/null
+++ b/web/manifest.html
@@ -0,0 +1,87 @@
+<html>
+<head>
+<title>Shapefile C Library V1.2</title>
+<link href="http://www.maptools.org/maptools.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h1>Shapelib Manifest</h1>
+
+<ul>
+<li> <b>web/index.html</b>: This file - general documentation on the 
+Shapefile C Library.<p>
+
+<li> <b><a href="shp_api.html">web/shp_api.html</a></b>: Documentation 
+for the API for accessing the .shp/.shx files. <p>
+
+<li> <b><a href="dbf_api.html">web/dbf_api.html</a></b>: Documentation 
+for the API for accessing the .dbf attribute files. <p>
+
+<li> <b>shpopen.c</b>: C code for access to .shp/.shx vertex files.<p>
+
+<li> <b>dbfopen.c</b>: C code for access to .dbf attribute file.<p>
+
+<li> <b>shapefil.h</b>:  Include file defining all the services of dbfopen.c 
+and shpopen.c.<p>
+
+<li> <b>contrib/</b>: A directory of "in progress" contributed programs
+from Carl Anderson.<p>
+
+<li> <b>dbfcreate.c</b>: Simple example program for creating a new .dbf file.
+     <p>
+
+<li> <b>dbfadd.c</b>: 
+	Simple example program for adding a record to a .dbf file.<p>
+
+<li> <b>dbfdump.c</b>: Simple example program for displaying the contents of
+		  a .dbf file.<p>
+
+<li> <b>shpcreate.c</b>: Simple example program for creating a new .shp and 
+.shx file.<p>
+
+<li> <b>shpadd.c</b>: Simple example program for adding a shape to an existing
+		  shape file.<p>
+
+<li> <b>shpdump.c</b>: Simple program for dumping all the vertices in a 
+		shapefile with an indicating of the parts.<p>
+
+<li> <b>shputils.c</b>: Complex contributed program capable of clipping and 
+		  appending
+                  shapefiles as well as a few other things.  Type shputils
+                  after building to get a full usage message.<p>
+
+<li> <b>Makefile</b>: A simple makefile to compile the library and example 
+		  programs.<p>
+
+<li> <b>makeshape.sh</b>: A simple script for running some of the example 
+programs.<p>
+
+<li> <b>shptest.c</b>: A simple test harnass to generate each of the supported
+		  types of shapefiles. <p>
+
+
+<li> <b>shptree.c</b>: Implements a simple quadtree algorithm for fast
+spatial searches of shapefiles.<p>
+
+<li> <b>shptreedump.c</b>: A simple mainly showing information on quad
+trees build using the quad tree api.<p>
+
+<li> <b>stream1.sh</b> - A test script, which should produce stream1.out.  
+Note this will only work if you have the example data downloaded.<p>
+
+<li> <b>stream1.out</b>: Expected output of stream1.sh test script.<p>
+
+<li> <b>stream2.sh</b>: A test script, which should produce stream2.out.<p>
+
+<li> <b>stream2.out</b>: Expected output of stream2.sh test script.<p>
+
+<li> <b>pyshapelib-0.1</b>: Prototype contributed Python bindings.<p>
+
+</ul>
+
+
+</body>
+</html>
+
+
+
diff --git a/web/release.html b/web/release.html
new file mode 100644
index 0000000..00170da
--- /dev/null
+++ b/web/release.html
@@ -0,0 +1,80 @@
+<html>
+<head>
+<title>Shapelib Release Notes</title>
+<link href="http://www.maptools.org/maptools.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h1>Shapelib Release Notes</h1>
+
+To get notification of new releases of Shapelib <i>subscribe</i> to 
+the project at www.freshmeat.net.  This is currently the only reliable
+way of finding out about new releases since there is no shapelib specific
+mailing list.<p>
+
+<b>Release 1.3.0</b>:
+<ul>
+<li> Major rework to us application provided hooks for file io, and error reporting (SAHooks).  
+<li> Added contrib/Shape_PointInPoly.cpp from Marko Podgorsek.  
+<li> Added shapelib tools documentation from Eduardo Patto Kanegae.
+<li> Added dbf deletion support.  
+<li> Added DBFAddNativeFieldType().
+<li> Added DBFDeleteField(), DBFReorderFields() and DBFAlterFields() to 
+rework DBF schema.
+<li> likely a variety of other changes - it has been eight years since 1.2.10!
+</ul>
+
+<b>Release 1.2.10</b>: Added SHPRewindObject() function, and shprewind utility
+program.  Added FTLogical, DBFReadLogicalAttribute() and 
+DBFWriteLogicalAttribute() (thanks to Olek Neyman). <p>
+
+<b>Release 1.2.9</b>: Good support for reading and writing NULL fields 
+in .dbf files, good support for NULL shapes and addition of the
+DBFGetFieldIndex() functions (all contributed by Jim Matthews).<p>
+
+An upgraded shputils.c has been contributed by Bill Miller.  Daniel 
+Morissette contributed DBFGetNativeFieldType().  Better error checking
+for disk errors in dbfopen.c.  Various other bug fixes and safety improvements.
+<p>
+
+<b>Release 1.2.8</b>: Added hacked libtool support (supplied by Jan)
+and "rpm ready" install logic.<p>
+
+<b>Release 1.2.7</b>: Fix record size (was 4 bytes too long).  Modify 
+SHPReadObject() to handle null shapes properly.  Use atof() instead of
+sscanf().  Support .DBF as well as .dbf.<p>
+
+<b>Release 1.2.6</b>: Now available under old MIT style license, or at the
+users option, LGPL.  Added the contrib directory of stuff from Carl Anderson
+and the shptree.c API for quadtree based spatial searches.<p>
+
+<b>Release 1.2.5</b>: SHPOpen() now forcably uses "rb" or "r+b" access string
+to avoid common mistakes on Windows.  Also fixed a serious bug with .dbf
+files with a 'F' field type.<p>
+
+<b>Release 1.2.4</b>: DBFOpen() will now automatically translate a .shp
+extension to .dbf for convenience.  SHPOpen() will try datasets with lower
+and uppercase extension.  DBFAddField() now returns the field number,
+not TRUE/FALSE.<p>
+
+<b>Release 1.2.3</b>: Disable writing measures to multi-patches as ArcView
+seems to puke on them (as reported by Monika Sester).  Add white space 
+trimming, and string/numeric attribute interchangability in DBF API
+as suggested by Steve Lime.  Dbfdump was updated to include several 
+reporting options.<p>
+
+<b>Release 1.2.2</b>: Added proper support for multipatch (reading and 
+writing) - this release just for testing purposes.<p>
+
+<b>Release 1.2</b> is mostly a rewrite of the .shp/.shx access API to account 
+for ArcView 3.x 3D shapes, and to encapsulate the shapes in a structure.  
+Existing code using the shapefile library will require substantial changes
+to use release 1.2.<p>
+
+<b>Release V1.1</b> has been built on a number of platforms, and used by a 
+number of people successfully.  V1.1 is the first release with the xBase API 
+documentation.<p>
+
+
+</body>
+</html>
diff --git a/web/shapelib-tools.html b/web/shapelib-tools.html
new file mode 100644
index 0000000..19ad547
--- /dev/null
+++ b/web/shapelib-tools.html
@@ -0,0 +1,352 @@
+<html>
+<head>
+<title>ShapeLib Tools - User Guide</title>
+<link href="http://www.maptools.org/maptools.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h1>ShapeLib Tools - User Guide</h1>
+ShapeLib is maintained by Frank Warmerdam<br>
+This guide was created by <a href="http://www.consultoria.eti.br" target="_show">Eduardo Patto Kanegae</a> < eduardo<i>~at~</i>consultoria<i>~dot~</i>eti<i>~dot~</i>br >
+<ul>
+	<li><a href="#dbfcreate">dbfcreate</a></li>
+	<li><a href="#dbfadd">dbfadd</a></li>
+	<li><a href="#dbfdump">dbfdump</a></li>
+	<li><a href="#shpcreate">shpcreate</a></li>
+	<li><a href="#shpadd">shpadd</a></li>
+	<li><a href="#shpdump">shpdump</a></li>
+	<li><a href="#shprewind">shprewind</a></li>
+	<li><i>Tools from ShapeLib 'contrib' directory</i>
+		<ul>
+			<li><a href="#dbfinfo">dbfinfo</a></li>
+			<li><a href="#dbfcat">dbfcat</a></li>
+			<li><a href="#shpinfo">shpinfo</a></li>
+			<li><a href="#shpcat">shpcat</a></li>
+			<li><a href="#shpcentrd">shpcentrd</a></li>
+			<li><a href="#shpdxf">shpdxf</a></li>
+			<li><a href="#shpfix">shpfix</a></li>
+			<li><a href="#shpproj">shpproj</a></li>
+		</ul>
+	</li>
+
+</ul>
+
+<h2><a name="dbfcreate">dbfcreate</a></h2>
+<b>Purpose</b>: creates a new and empty .dbf file.
+<br>
+<b>Usage</b>: <font face="courier">dbfcreate xbase_file [[-s field_name width],[-n field_name width decimals]]...</font>
+<br>
+<ul>
+	<li><b>xbase_file</b>: the name of xBase file to be created. Doesn't need the extension.</li>
+	<li><b>-s field_name width</b>: creates a string field with name <u>field_name</u> and size <u>width</u>.</li>
+	<li><b>-n field_name width decimals</b>: creates a numeric field with name <u>field_name</u>, width of <u>width</u> and with decimals places sized by <u>decimals</u>.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ dbfcreate testbase -s NAME 20, -n AREA 9 3, -n VALUE 9 2</font>
+<br># this will create a file named testbase.dbf with 3 fields: NAME ( string (20)),
+AREA ( float (9,3)) and VALUE ( float (9,2))
+<br>
+<hr>
+
+<h2><a name="dbfadd">dbfadd</a></h2>
+<b>Purpose</b>: adds a record into an existing .dbf file.
+<br>
+<b>Usage</b>: <font face="courier">dbfadd xbase_file field_values</font>
+<br>
+<ul>
+	<li><b>xbase_file</b>: the name of an existing xBase file.</li>
+	<li><b>field_values</b>: list of values to be inserted into the xBase file.
+	You must specify a number of values equal to the number of fields the xBase file has.
+	The order of values must also reflect the order of fields inside xBase file.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ dbfadd testbase.dbf REGION1 25.656 150.22</font>
+<br># assuming that testbase.dbf has 3 fields( NAME, AREA and VALUE), this command line
+will insert a new record into testbase.dbf with the value "REGION1" for NAME,
+'25.656' for AREA and '150.22' for VALUE field.
+<br>
+<hr>
+
+<h2><a name="dbfdump">dbfdump</a></h2>
+<b>Purpose</b>: dumps the content of a xBase file to the terminal.
+<br>
+<b>Usage</b>: <font face="courier">dbfdump [-h] [-r] [-m] xbase_file</font>
+<br>
+<ul>
+	<li><b>-h</b>: output header info( field descriptions).</li>
+	<li><b>-r</b>: output raw field info, numeric values not reformatted.</li>
+	<li><b>-m</b>: output one line per field.</li>
+	<li><b>xbase_file</b>: the name of an existing xBase file.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ dbfdump -h testbase.dbf</font>
+<br># assuming that testbase.dbf has 1 record( inserted by previous example using 'dbfadd'),
+this command line will produce the following output:<br>
+<font face="courier">
+Field 0: Type=String, Title=`NAME', Width=20, Decimals=0<br>
+Field 1: Type=Double, Title=`AREA', Width=9, Decimals=3<br>
+Field 2: Type=Double, Title=`VALUE', Width=9, Decimals=2<br>
+NAME                      AREA     VALUE<br>
+REGION1                 25.656    150.22
+</font>
+<br>
+<hr>
+
+<h2><a name="shpcreate">shpcreate</a></h2>
+<b>Purpose</b>: creates a new and empty shapefile.
+<br>
+<b>Usage</b>: <font face="courier">shpcreate shp_file [point|arc|polygon|multipoint]</font>
+<br>
+<ul>
+	<li><b>shp_file</b>: the name of shapefile to be created. Doesn't need the extension.</li>
+	<li><b>point/arc/polygon/multipoint</b>: the type of shapefile that you wish to create. You must specify a valid option.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpcreate testpolygon polygon</font>
+<br># this will create a point shapefile named testpolygon( in fact testpolygon.shp and testpolygon.shx will be created).
+<br>
+<hr>
+
+<h2><a name="shpadd">shpadd</a></h2>
+<b>Purpose</b>: adds a shape into an existing shapefile.
+<br>
+<b>Usage</b>: <font face="courier">shpadd shp_file [[x y] [+]]*</font>
+<br>
+<ul>
+	<li><b>shp_file</b>: the name of an existing shapefile.</li>
+	<li><b>x<sub><i>1</i></sub> y<sub><i>1</i></sub> x<sub><i>2</i></sub> y<sub><i>2</i></sub> ... x<sub><i>n</i></sub> y<sub><i>n</i></sub></b>: the set of x,y coordinates that describes the shape that you wish to add. Note that you must specify the correct number of parameters for a given type of shapefile. e.g.: for point shapefiles you have to pass 1 pair of XY coordinates and for a polygon shapefile you should pass at least 4 pairs of XY coordinates( where the first and the last point must have the same coordinates).</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpadd testpolygon 100000 7000000 250000 6500000 200000 6000000 100000 7000000</font>
+<br># assuming that testpolygon is a polygon shapefile, this command line will insert a new shape( a triangle) into testpolygon with the following XY coordinates:<br>
+vertice 0: 100000 7000000 ( this will also be the vertice where the shape starts and ends)<br>
+vertice 1: 250000 6500000<br>
+vertice 2: 200000 6000000<br>
+vertice 3: 100000 7000000<br>
+<hr>
+
+<h2><a name="shpdump">shpdump</a></h2>
+<b>Purpose</b>: dumps content of shapefile showing information like shape type, file extents, total of objects and vertices coordinates.
+<br>
+<b>Usage</b>: <font face="courier">shpdump [-validate] shp_file</font>
+<br>
+<ul>
+	<li><b>-validate</b>: count the number of objects that has invalid ring orderings.</li>
+	<li><b>shp_file</b>: the name of an existing shapefile.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpdump testpolygon</font>
+<br># assuming that testpolygon is an existing shapefile previously created, this command line will output the following result:
+<pre>Shapefile Type: Polygon   # of Shapes: 1
+
+File Bounds: (  100000.000, 6000000.000,0,0)
+         to  (  250000.000, 7000000.000,0,0)
+
+Shape:0 (Polygon)  nVertices=4, nParts=1
+  Bounds:(  100000.000, 6000000.000, 0, 0)
+      to (  250000.000, 7000000.000, 0, 0)
+     (  100000.000, 7000000.000, 0, 0) Ring
+     (  250000.000, 6500000.000, 0, 0)
+     (  200000.000, 6000000.000, 0, 0)
+     (  100000.000, 7000000.000, 0, 0)</pre>
+<hr>
+
+<h2><a name="shprewind">shprewind</a></h2>
+<b>Purpose</b>: validates and resets the winding order of rings in polygon geometries to match the ordering required by shapefile specification. This is usefull for shapefiles having troubles when checked with a 'shpdump -validate'.
+<br>
+<b>Usage</b>: <font face="courier">shprewind in_shp_file out_shp_file</font>
+<br>
+<ul>
+	<li><b>in_shp_file</b>: the name of an existing shapefile.</li>
+	<li><b>out_shp_file</b>: the name of the new fixed shapefile that will be created.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shprewind badshapefile newshapefile</font>
+<br>
+<hr>
+
+<h2><a name="dbfinfo">dbfinfo</a></h2>
+<b>Purpose</b>: displays basic information for a given xBase file, like number of columns, number of records and type of each column.
+<br>
+<b>Usage</b>: <font face="courier">dbfinfo xbase_file</font>
+<br>
+<ul>
+	<li><b>xbase_file</b>: the name of an existing xBase file.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ dbfinfo testbase</font>
+<br>
+<pre>Info for testbase.dbf
+3 Columns,  1 Records in file
+           NAME          string  (20,0)
+           AREA           float  (9,3)
+          VALUE           float  (9,2)
+</pre>
+<br>
+<hr>
+
+<h2><a name="dbfcat">dbfcat</a></h2>
+<b>Purpose</b>: appends the records of a source xBase file into a destiny xBase file. Both files must have the same number of fields.
+<br>
+<b>Usage</b>: <font face="courier">dbfcat [-v] [-f] from_DBFfile to_DBFfile</font>
+<br>
+<ul>
+	<li><b>-v</b>: verbose mode.</li>
+	<li><b>-f</b>: forces data convertion if data field types is not the same at both files or if is there any null value into <u>from_DBFfile</u>.</li>
+	<li><b>from_DBFfile</b>: source xBase file.</li>
+	<li><b>to_DBFfile</b>: destiny xBase file.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ dbfcat -v testbase1 testbase2</font>
+<br>
+<hr>
+
+<h2><a name="shpinfo">shpinfo</a></h2>
+<b>Purpose</b>: displays basic information for a given shapefile, like shapefile type, number of objects and its extents.
+<br>
+<b>Usage</b>: <font face="courier">shpinfo shp_file</font>
+<br>
+<ul>
+	<li><b>shp_file</b>: the name of an existing shapefile.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpinfo testpolygon</font>
+<br>
+<pre>Info for testpolygon
+Polygon(5), 1 Records in file
+File Bounds: (         100000,        6000000)
+        (         250000,        7000000)</pre>
+<hr>
+
+<h2><a name="shpcat">shpcat</a></h2>
+<b>Purpose</b>: appends the content of a source shapefile into a destiny shapefile. Both files must be the same shapefile type.
+<br>
+<b>Usage</b>: <font face="courier">shpcat from_shpfile to_shpfile</font>
+<br>
+<ul>
+	<li><b>from_shpfile</b>: source shapefile</li>
+	<li><b>to_shpfile</b>: destiny shapefile</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpcat shapefile1 shapefile2</font>
+<br>
+<hr>
+
+<h2><a name="shpcentrd">shpcentrd</a></h2>
+<b>Purpose</b>: computes XY centroid for polygon shapefiles.
+<br>
+<b>Usage</b>: <font face="courier">shpcentrd shp_file new_shp_file</font>
+<br>
+<ul>
+	<li><b>shp_file</b>: the name of an existing polygon shapefile.</li>
+	<li><b>new_shp_file</b>: the name of the point shapefile that will created.</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpcentrd apolygonfile pointcentrd</font>
+<br>
+<hr>
+
+<h2><a name="shpdxf">shpdxf</a></h2>
+<b>Purpose</b>: creates a DXF file from an existing shapefile.
+<br>
+<b>Usage</b>: <font face="courier">shpdxf shapefile {idfield}</font>
+<br>
+<ul>
+	<li><b>shapefile</b>: the name of an existing shapefile.</li>
+	<li><b>idfield</b>: explain</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpdxf testshapefile IDFIELD</font>
+<br># explain the command
+<br>
+<hr>
+
+<h2><a name="shpfix">shpfix</a></h2>
+<b>Purpose</b>: Utility program to fix nulls and inconsistencies in Shapefiles
+as happens from time to time.
+<br>
+<b>Usage</b>: <font face="courier">shpfix shpfile new_file <Record# to Blank></font>
+<br>
+<ul>
+	<li><b>shpfile</b>: input file</li>
+	<li><b>new_file</b>: output file</li>
+</ul>
+<b>Example</b>
+<br>
+<font face="courier">$ shpfix broken fixed</font>
+<br>
+<hr>
+
+<h2><a name="shpproj">shpproj</a></h2>
+<b>Purpose</b>: Reproject Shapefiles using PROJ.4
+<br>
+<b>Usage</b>: <font face="courier">shpproj shp_file new_shp ( -i=in_proj_file | -i="in_params" | -i=geographic ) ( -o=out_info_file | -o="out_params" | -o=geographic ) </font>
+<br>
+<ul>
+	<li><b>param1</b>: explain</li>
+	<li><b>param2</b>: explain</li>
+</ul>
+<p>
+
+<b>INPUT</b><br>
+  Input can come from one of three sources.  A projection parameter file, 
+  directly through parameters or geographic. If the shapefile has an associated
+  prj file, name the same as the shapefile but ending in ".prj" it will be used
+  by default ignoring all other parameters.  If input is omitted it defaults to
+  geographic, unless the default prj file exists.<p>
+
+<b>OUTPUT</b><br>
+  Output can come from one of three sources.  A projection parameter file,
+  directly through parameters or geographic.  If output is omitted it defaults
+  to geographic.<p>
+
+<b>PROJECTION PARAMETER FILE</b><br>
+  This file MUST end with the extension ".prj".  It has the form of one
+  projection parameter per line.  Parameters can be in any order.  The
+  projection parameters are those used to define a PROJ.4 projection.<p>
+
+<b>PROJECTION PARAMETERS</b><br>
+  Are the same as used by proj and invproj.<p>
+<pre>
+  use      proj -lP   to see available projections
+	   proj -lu   to see available units
+	   proj -le   to see available ellipsoid
+</pre>
+
+Or visit the PROJ.4 web page at <a href="http://www.remotesensing.org/proj">http://www.remotesensing.org/proj</a> for more details.<p>
+
+<p>
+
+<b>Example</b></br>
+
+the following example projects file rowtest to row3, moving data from Stateplane NAD83  zone 1002 to utm zone 16 in meters<p>
+
+<pre>
+ 
+shpproj rowtest row -i="init=nad83:1002 units=us-ft" -o="proj=utm zone=16 units=m"
+
+shpproj rowtest row3 -o="proj=utm zone=18 units=m" -i="zone=16 proj=utm units=us-ft"
+
+shpproj rowtest row3 -o="proj=utm zone=18 units=m" 
+
+shpproj rowtest row3 -i=myfile.prj -o=geographic
+shpproj rowtest row3 -is=myfile.prj
+</pre>
+
+<hr>
+
+</body>
+</html>
diff --git a/shp_api.html b/web/shp_api.html
similarity index 100%
rename from shp_api.html
rename to web/shp_api.html

-- 
Library for reading and writing ArcView Shapefiles



More information about the Pkg-grass-devel mailing list